8. Seguridad de la configuración de Django en producción
El error más habitual al desplegar Django en producción es dejar DEBUG=True. Ante un error de la aplicación, esto muestra al usuario la pila completa de llamadas, junto con variables de entorno y fragmentos de código, lo que supone una fuga grave de información sobre la estructura interna de la aplicación.
El SECRET_KEY que utiliza Django para firmar sesiones y tokens debe ser único para cada despliegue y no debe guardarse en el repositorio de código, sino configurarse como una variable de entorno en la configuración de la aplicación en Saplo, fuera del propio código fuente.
ALLOWED_HOSTS debe contener exactamente los dominios en los que la aplicación está disponible, no un asterisco que permita todos los hosts. Esta es una protección básica contra la inyección de la cabecera Host, especialmente importante en aplicaciones que reciben datos de usuarios de internet.
Conviene separar lógicamente los archivos estáticos y los archivos multimedia subidos por los usuarios (uploads), sirviendo los archivos estáticos de la aplicación mediante nginx y los archivos cargados por los usuarios mediante un mecanismo independiente con los permisos adecuados. Así se evita que un usuario pueda subir y ejecutar un script malicioso en el servidor.
Actualizar Django y los paquetes de Python que uses (requirements.txt) debería ser una práctica habitual. Igual que en el ecosistema de Node.js, las dependencias obsoletas son un vector frecuente de vulnerabilidades conocidas que ya están corregidas y que los escáneres automatizados suelen detectar.
Para las aplicaciones que almacenan datos personales de usuarios, conviene configurar expresamente las opciones de sesión (tiempo de expiración, opciones Secure y HttpOnly de las cookies), algo que Django admite de forma nativa, pero que requiere una configuración explícita en los ajustes del proyecto y no da resultados correctos en todos los escenarios si se usan solo los valores predeterminados. Merece la pena revisar esta configuración junto con la lista completa de ajustes de seguridad de Django antes del primer despliegue en producción, en lugar de descubrir que falta un ajuste solo después de un incidente real de seguridad.