Por framework
Seguridad en Django — una referencia de endurecimiento para producción
Una referencia de endurecimiento para producción de Django: una lista de verificación por prioridad más DEBUG/ALLOWED_HOSTS, SECRET_KEY, CVE de pip, configuración de seguridad de producción, autorización, inyección y SSRF. Defensiva, sin pasos de ataque.
Para: cualquiera que gestione una aplicación Django. Aquí no hay pasos de ataque — esta es una referencia de trabajo para el endurecimiento: una lista de verificación ordenada por prioridad, guía por área y autoverificación. Para el panorama entre frameworks, consulta el centro de seguridad por framework.
Lista de endurecimiento ordenada por prioridad
Recorre esta tabla de arriba abajo. P0 es un prerrequisito, P1 es la fuente más frecuente de incidentes, P2 es higiene operativa continua.
P0 ── Prerrequisito (hazlo primero)
DEBUG=False + ALLOWED_HOSTS / externalizar SECRET_KEY / parchear rápido los CVE de dependencias pip
P1 ── Principal fuente de incidentes
Configuración de seguridad de producción (SSL/HSTS/cookies) / autorización (alcance de propietario)
P2 ── Higiene operativa
Inyección y salida / CSRF, sesiones, admin / SSRF, subidas
| Prioridad | Control | Detalles (Django) |
|---|---|---|
| P0 | DEBUG/ALLOWED_HOSTS | Producción con DEBUG=False + ALLOWED_HOSTS configurado. No expongas errores detallados |
| P0 | SECRET_KEY | Desde el entorno, no en el código/repositorio. Rótala si se filtra |
| P0 | CVE de dependencias pip | Monitoriza con pip-audit / osv-scanner; juzga por la versión en ejecución, parchea rápido |
| P1 | Configuración de seguridad de producción | SECURE_SSL_REDIRECT, SECURE_HSTS_SECONDS, SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE, SECURE_CONTENT_TYPE_NOSNIFF |
| P1 | Autorización explícita | Inicio de sesión requerido + permisos + filter(user=request.user) para el alcance de propietario |
| P2 | Inyección/salida | Usa binding mediante el ORM. Evita la interpolación en raw()/extra(). No pases entrada a mark_safe/` |
| P2 | CSRF/sesiones/admin | No deshabilites el CSRF (por defecto). Restringe la exposición de admin |
| P2 | SSRF/subidas | Lista de permitidos para las peticiones del lado del servidor + bloquear IPs internas. Valida las subidas, almacénalas fuera de la superficie pública |
1. DEBUG y ALLOWED_HOSTS (P0)
- Asegura
DEBUG=Falseen producción. Activado, la página de error expone ajustes, variables de entorno y trazas de pila, extraíbles mediante errores deliberados. - Configura
ALLOWED_HOSTScorrectamente para evitar la operación bajo hosts inesperados. Evita que se muestren errores detallados externamente.
2. SECRET_KEY (P0)
SECRET_KEYsustenta las cookies firmadas, las sesiones, los tokens CSRF y los restablecimientos de contraseña. Cárgala desde una variable de entorno o un gestor de secretos, no del código/repositorio.- Rótala de inmediato si se filtra. Mantenla fuera de los directorios públicos y de las páginas DEBUG (→ mantén los secretos fuera de los directorios públicos).
3. CVE de dependencias pip (P0)
- Monitoriza de forma automática los CVE conocidos con pip-audit u osv-scanner, juzga por la versión en ejecución y parchea rápido (→ monitorizar los CVE de dependencias · el manual de respuesta a vulnerabilidades).
- Mantén Django y Python en versiones con soporte y no dejes versiones EOL en su sitio.
4. Configuración de seguridad de producción (P1)
Django configura buena parte de su defensa mediante SecurityMiddleware. Establece estos para producción:
SECURE_SSL_REDIRECT(forzar HTTPS) ·SECURE_HSTS_SECONDS(+INCLUDE_SUBDOMAINS/PRELOAD)SESSION_COOKIE_SECURE/CSRF_COOKIE_SECURE(cookies solo por HTTPS)SECURE_CONTENT_TYPE_NOSNIFF, etc.- Ejecuta
manage.py check --deploypara revelar mecánicamente las carencias en estos.
5. Autorización (P1 — la principal fuente)
Común (peligroso)
- inicio de sesión requerido, pero sin alcance de propietario
- querysets sobre todo, sin filtrado por ID
- confiar en URLs ocultas / IDs difíciles de adivinar
- olvidar una comprobación de permisos en algunas vistas
Correcto
- inicio de sesión requerido + comprobaciones de permisos explícitas
- las lecturas también se acotan al propietario (p. ej.
filter(user=request.user)) - verificado en cada ruta de lectura/actualización/borrado
- autorización construida explícitamente, no dejada a los valores por defecto
Consulta qué es el IDOR. La autenticación y la autorización son distintas; autoriza cerca de los datos.
6. Inyección y salida (P2)
- SQL: usa binding mediante el ORM. No construyas consultas con
raw()/extra()ni con interpolación de cadenas (→ qué es la inyección SQL). - XSS: las plantillas hacen autoescapado por defecto. No pases entrada del usuario a
mark_safe/|safe(→ qué es el XSS). - Deserialización: no cargues
pickleno confiable (puede llevar a la ejecución de código).
7. CSRF, sesiones, admin (P2)
- No deshabilites la protección CSRF por defecto (→ qué es el CSRF).
- Restringe la exposición de admin (límites de acceso, cambio de URL, autenticación multifactor). Mantén la defensa contra clickjacking (
X-Frame-Optionspor defecto). - Aplica secure/httponly/samesite a las sesiones y regenéralas al iniciar sesión.
8. SSRF, subidas, cabeceras (P2)
- La obtención del lado del servidor de URLs proporcionadas por el usuario debe restringir los destinos a una lista de permitidos y bloquear el alcance a IPs internas/metadatos (→ qué es el SSRF).
- Valida las subidas (tipo/tamaño) y almacénalas fuera de la superficie pública.
- Comprueba las cabeceras de tu propio sitio con el verificador de cabeceras de seguridad.
Verifica: ¿está tu Django realmente endurecido?
Construirlo no es el final — solo está hecho una vez que lo has comprobado. Estas son autocomprobaciones defensivas contra tu propio entorno.
Comprueba mecánicamente las carencias
python manage.py check --deploy y confirma que los avisos están resueltos.Producción no expone DEBUG
La autorización se sostiene
Secretos y dependencias
SECRET_KEY no está en el repositorio, y que pip-audit/osv está limpio.La opinión de este sitio: pilas incluidas, pero la configuración y la autorización dependen de ti
Django protege mucho por defecto, pero la configuración de producción (DEBUG/SECRET_KEY/ALLOWED_HOSTS/SSL) y la autorización son cosas que debes acertar por entorno y por aplicación. Los incidentes que seguimos viendo son menos ataques elaborados que patrones de configuración/operación: «debug estaba abierto en producción», «se expuso un secreto», «no había autorización». Por eso el centro de gravedad es ajustar la configuración de producción, mantener los secretos privados y hacer la autorización explícita. Integrar check --deploy en tu proceso es el atajo.
Lee a continuación
- Centro: seguridad por framework · seguridad en Laravel (similar producción-DEBUG / exposición de secretos)
- Práctica: el manual de respuesta a vulnerabilidades · monitorizar los CVE de dependencias · mantén los secretos fuera de los directorios públicos
- Glosario: qué es el IDOR · inyección SQL · XSS · CSRF · SSRF
- Herramientas: verificador de cabeceras de seguridad
FAQ
Q¿Qué debo hacer primero para asegurar Django?
Los tres elementos P0: (1) asegura DEBUG=False en producción y configura ALLOWED_HOSTS correctamente; (2) carga SECRET_KEY desde el entorno (no en el código/repositorio) y rótala si se filtra; (3) monitoriza de forma automática los CVE de dependencias pip y parchea rápido, juzgando por la versión en ejecución. Luego, pasa a la configuración de seguridad de producción (SSL/HSTS/cookies) y a la autorización. manage.py check --deploy revela mecánicamente los ajustes que faltan.
Q¿Qué tiene de peligroso dejar DEBUG=True en producción?
Con DEBUG activado, la página de error puede mostrar detalles internos — ajustes, variables de entorno, trazas de pila. Un atacante puede provocar errores a propósito para extraerlos. En producción, establece siempre DEBUG=False y configura ALLOWED_HOSTS correctamente. Además, evita que se muestren errores detallados externamente y revisa el servido de estáticos/media para producción.
Q¿Por qué es importante SECRET_KEY?
SECRET_KEY sustenta las cookies y sesiones firmadas, los tokens CSRF y los restablecimientos de contraseña. Una filtración puede llevar a falsificarlos o manipularlos. No la pongas en el código ni en el repositorio — cárgala desde una variable de entorno o un gestor de secretos, y rótala de inmediato si se filtra. Además, evita que quede expuesta mediante un directorio público o una página DEBUG.
Q¿Qué ajustes de seguridad de producción de Django debo comprobar?
Los relacionados con SecurityMiddleware: SECURE_SSL_REDIRECT (forzar HTTPS), SECURE_HSTS_SECONDS (HSTS), SESSION_COOKIE_SECURE / CSRF_COOKIE_SECURE (cookies seguras), SECURE_CONTENT_TYPE_NOSNIFF, y más, configurados para producción. Ejecutar manage.py check --deploy revela mecánicamente las carencias en estos.
Q¿Cómo gestiono las vulnerabilidades de dependencias pip?
Monitoriza de forma automática los CVE conocidos con pip-audit u osv-scanner y parchea rápido, juzgando por la versión en ejecución. Mantén Django y Python en versiones con soporte y no dejes versiones EOL en su sitio. La frescura de las dependencias es un factor más realista en los incidentes que los ataques elaborados.