Este documento es una descripción general de las funciones de seguridad de Django. Incluye consejos sobre cómo proteger un sitio con tecnología Django.

Protección de secuencias de comandos entre sitios (XSS)

Los ataques XSS permiten a un usuario inyectar scripts del lado del cliente en los navegadores de otros usuarios. Esto generalmente se logra almacenando los scripts maliciosos en la base de datos donde serán recuperados y mostrados a otros usuarios, o haciendo que los usuarios hagan clic en un enlace que hará que el navegador del usuario ejecute el JavaScript del atacante. Sin embargo, los ataques XSS pueden tener su origen en cualquier fuente de datos que no sea de confianza, como cookies o servicios web, siempre que los datos no estén lo suficientemente desinfectados antes de incluirlos en una página.

El uso de plantillas de Django lo protege contra la mayoría de los ataques XSS. Sin embargo, es importante comprender qué protecciones proporciona y sus limitaciones.

Plantillas de Django escapar de personajes específicos que son particularmente peligrosos para HTML. Si bien esto protege a los usuarios de la mayoría de las entradas maliciosas, no es del todo infalible. Por ejemplo, no protegerá lo siguiente:

<style class={{ var }}>...</style>

Si var se establece en 'class1 onmouseover=javascript:func()', esto puede resultar en una ejecución de JavaScript no autorizada, dependiendo de cómo el navegador muestre HTML imperfecto. (Citar el valor del atributo solucionaría este caso).

También es importante tener especial cuidado al utilizar is_safe con etiquetas de plantilla personalizadas, safe etiqueta de plantilla, mark_safey cuando autoescape está desactivado.

Además, si está utilizando el sistema de plantillas para generar algo que no sea HTML, es posible que haya caracteres y palabras completamente separados que requieran escapar.

También debe tener mucho cuidado al almacenar HTML en la base de datos, especialmente cuando ese HTML se recupera y se muestra.

Protección contra falsificación de solicitudes entre sitios (CSRF)

Los ataques CSRF permiten que un usuario malintencionado ejecute acciones utilizando las credenciales de otro usuario sin el conocimiento o consentimiento de ese usuario.

Django tiene protección incorporada contra la mayoría de los tipos de ataques CSRF, siempre que tenga habilitado y usado donde corresponda. Sin embargo, como ocurre con cualquier técnica de mitigación, existen limitaciones. Por ejemplo, es posible deshabilitar el módulo CSRF globalmente o para vistas particulares. Solo debe hacer esto si sabe lo que está haciendo. Hay otros limitaciones si su sitio tiene subdominios que están fuera de su control.

La protección CSRF funciona comprobando un secreto en cada solicitud POST. Esto asegura que un usuario malintencionado no pueda “reproducir” un formulario POST en su sitio web y que otro usuario que haya iniciado sesión envíe ese formulario sin saberlo. El usuario malintencionado debería conocer el secreto, que es específico del usuario (mediante una cookie).

Cuando se implementa con HTTPS, CsrfViewMiddleware comprobará que el encabezado de referencia HTTP esté configurado en una URL del mismo origen (incluidos el subdominio y el puerto). Debido a que HTTPS proporciona seguridad adicional, es imperativo garantizar que las conexiones utilicen HTTPS donde esté disponible mediante el reenvío de solicitudes de conexión inseguras y el uso de HSTS para los navegadores compatibles.

Tenga mucho cuidado al marcar vistas con el csrf_exempt decorador a menos que sea absolutamente necesario.

Protección de inyección SQL

La inyección SQL es un tipo de ataque en el que un usuario malintencionado puede ejecutar código SQL arbitrario en una base de datos. Esto puede provocar la eliminación de registros o la filtración de datos.

Los conjuntos de consultas de Django están protegidos de la inyección de SQL, ya que sus consultas se construyen mediante la parametrización de consultas. El código SQL de una consulta se define por separado de los parámetros de la consulta. Dado que los parámetros pueden ser proporcionados por el usuario y, por lo tanto, no seguros, el controlador de la base de datos subyacente los escapa.

Django también les da a los desarrolladores el poder de escribir consultas sin procesar o ejecutar sql personalizado. Estas capacidades deben usarse con moderación y siempre debe tener cuidado de escapar correctamente de cualquier parámetro que el usuario pueda controlar. Además, debe tener cuidado al usar extra() y RawSQL.

Protección contra el secuestro de clics

Clickjacking es un tipo de ataque en el que un sitio malicioso envuelve otro sitio en un marco. Este ataque puede provocar que un usuario desprevenido sea engañado para que realice acciones no deseadas en el sitio de destino.

Django contiene protección contra clickjacking en forma de X-Frame-Options middleware que en un navegador compatible puede evitar que un sitio se represente dentro de un marco. Es posible deshabilitar la protección por vista o configurar el valor exacto del encabezado enviado.

El middleware se recomienda encarecidamente para cualquier sitio que no necesite tener sus páginas envueltas en un marco por sitios de terceros, o que solo necesite permitirlo para una pequeña sección del sitio.

SSL / HTTPS

Siempre es mejor para la seguridad implementar su sitio detrás de HTTPS. Sin esto, es posible que los usuarios malintencionados de la red rastreen las credenciales de autenticación o cualquier otra información transferida entre el cliente y el servidor y, en algunos casos, activo Atacantes de red: para alterar los datos que se envían en cualquier dirección.

Si desea la protección que proporciona HTTPS y la ha habilitado en su servidor, es posible que necesite algunos pasos adicionales:

  • Si es necesario, configure SECURE_PROXY_SSL_HEADER, asegurándose de que ha entendido las advertencias allí a fondo. No hacer esto puede resultar en vulnerabilidades CSRF, ¡y no hacerlo correctamente también puede ser peligroso!
  • Colocar SECURE_SSL_REDIRECT para True, para que las solicitudes a través de HTTP se redirijan a HTTPS.

    Tenga en cuenta las advertencias a continuación SECURE_PROXY_SSL_HEADER. Para el caso de un proxy inverso, puede ser más fácil o más seguro configurar el servidor web principal para que realice la redirección a HTTPS.

  • Utilice cookies ‘seguras’.

    Si un navegador se conecta inicialmente a través de HTTP, que es el predeterminado para la mayoría de los navegadores, es posible que se filtren las cookies existentes. Por esta razón, debe configurar su SESSION_COOKIE_SECURE y CSRF_COOKIE_SECURE ajustes a True. Esto indica al navegador que solo envíe estas cookies a través de conexiones HTTPS. Tenga en cuenta que esto significará que las sesiones no funcionarán a través de HTTP, y la protección CSRF evitará que se acepten datos POST a través de HTTP (lo que estará bien si está redirigiendo todo el tráfico HTTP a HTTPS).

  • Usar Seguridad de transporte estricta HTTP (HSTS)

    HSTS es un encabezado HTTP que informa a un navegador que todas las conexiones futuras a un sitio en particular siempre deben usar HTTPS. Combinado con la redirección de solicitudes a través de HTTP a HTTPS, esto garantizará que las conexiones siempre disfruten de la seguridad adicional de SSL siempre que se haya producido una conexión exitosa. HSTS puede configurarse con SECURE_HSTS_SECONDS, SECURE_HSTS_INCLUDE_SUBDOMAINS, y SECURE_HSTS_PRELOADo en el servidor web.

Validación del encabezado del host

Django usa el Host encabezado proporcionado por el cliente para construir URL en ciertos casos. Si bien estos valores están desinfectados para evitar ataques de Cross Site Scripting, una Host value se puede utilizar para la falsificación de solicitudes entre sitios, ataques de envenenamiento de caché y enlaces de envenenamiento en correos electrónicos.

Porque incluso las configuraciones de servidor web aparentemente seguras son susceptibles a falsificaciones Host encabezados, Django valida Host encabezados contra el ALLOWED_HOSTS entorno en el django.http.HttpRequest.get_host() método.

Esta validación solo se aplica a través de get_host(); si su código accede al Host encabezado directamente desde request.META está pasando por alto esta protección de seguridad.

Para obtener más detalles, consulte el ALLOWED_HOSTS documentación.

Advertencia

Las versiones anteriores de este documento recomendaban configurar su servidor web para asegurarse de que valida el HTTP entrante Host encabezados. Si bien esto todavía se recomienda, en muchos servidores web comunes, una configuración que parece validar la Host De hecho, es posible que el encabezado no lo haga. Por ejemplo, incluso si Apache está configurado de manera que su sitio Django se atienda desde un host virtual no predeterminado con el ServerName establecido, todavía es posible que una solicitud HTTP coincida con este host virtual y proporcione una Host encabezamiento. Por lo tanto, Django ahora requiere que establezca ALLOWED_HOSTS explícitamente en lugar de depender de la configuración del servidor web.

Además, Django requiere que habilites explícitamente el soporte para el X-Forwarded-Host encabezado (a través del USE_X_FORWARDED_HOST ajuste) si su configuración lo requiere.

Política de referencias

Los navegadores utilizan Referer encabezado como una forma de enviar información a un sitio sobre cómo llegaron los usuarios. Estableciendo un Política de referencias puede ayudar a proteger la privacidad de sus usuarios, restringiendo bajo qué circunstancias el Referer El encabezado está configurado. Ver la sección de política de referencia de la referencia de middleware de seguridad para detalles.

Seguridad de la sesión

Similar a Limitaciones de CSRF requerir que un sitio se implemente de manera que los usuarios que no sean de confianza no tengan acceso a ningún subdominio, django.contrib.sessions también tiene limitaciones. Ver la sección de la guía de temas de la sesión sobre seguridad para detalles.

Contenido subido por el usuario

Nota

Considerar servir archivos estáticos desde un servicio en la nube o CDN para evitar algunos de estos problemas.

  • Si su sitio acepta la carga de archivos, se recomienda encarecidamente que limite estas cargas en la configuración de su servidor web a un tamaño razonable para evitar ataques de denegación de servicio (DOS). En Apache, esto se puede configurar fácilmente usando el LimitRequestBody directiva.
  • Si está sirviendo sus propios archivos estáticos, asegúrese de que controladores como Apache mod_php, que ejecutarían archivos estáticos como código, están deshabilitados. No desea que los usuarios puedan ejecutar código arbitrario cargando y solicitando un archivo especialmente diseñado.
  • El manejo de carga de medios de Django presenta algunas vulnerabilidades cuando esos medios se sirven de formas que no siguen las mejores prácticas de seguridad. Específicamente, un archivo HTML se puede cargar como una imagen si ese archivo contiene un encabezado PNG válido seguido de HTML malicioso. Este archivo pasará la verificación de la biblioteca que usa Django para ImageField procesamiento de imágenes (almohada). Cuando este archivo se muestra posteriormente a un usuario, puede mostrarse como HTML según el tipo y la configuración de su servidor web.

    No existe una solución técnica a prueba de balas a nivel de marco para validar de forma segura todo el contenido de los archivos subidos por el usuario; sin embargo, hay algunos otros pasos que puede seguir para mitigar estos ataques:

    1. Se puede prevenir una clase de ataques sirviendo siempre contenido subido por el usuario desde un dominio de nivel superior o de segundo nivel distinto. Esto evita cualquier exploit bloqueado por política del mismo origen protecciones tales como secuencias de comandos de sitios cruzados. Por ejemplo, si su sitio se ejecuta en example.com, querrás publicar contenido subido (el MEDIA_URL ajuste) de algo como usercontent-example.com. Es no suficiente para publicar contenido de un subdominio como usercontent.example.com.
    2. Más allá de esto, las aplicaciones pueden optar por definir una lista de extensiones de archivo permitidas para los archivos cargados por el usuario y configurar el servidor web para que solo sirva dichos archivos.

Temas de seguridad adicionales

Si bien Django proporciona una buena protección de seguridad fuera del box, sigue siendo importante implementar correctamente su aplicación y aprovechar la protección de seguridad del servidor web, el sistema operativo y otros componentes.

  • Asegúrese de que su código Python esté fuera de la raíz del servidor web. Esto asegurará que su código Python no se sirva accidentalmente como texto sin formato (o se ejecute accidentalmente).
  • Tenga cuidado con cualquier archivos cargados por el usuario.
  • Django no limita las solicitudes para autenticar usuarios. Para protegerse contra ataques de fuerza bruta contra el sistema de autenticación, puede considerar implementar un complemento de Django o un módulo de servidor web para acelerar estas solicitudes.
  • Mantener su SECRET_KEY un secreto.
  • Es una buena idea limitar la accesibilidad de su sistema de almacenamiento en caché y su base de datos mediante un firewall.
  • Eche un vistazo al Proyecto de seguridad de aplicaciones web abiertas (OWASP) Lista de los 10 principales que identifica algunas vulnerabilidades comunes en aplicaciones web. Si bien Django tiene herramientas para abordar algunos de los problemas, otros problemas deben tenerse en cuenta en el diseño de su proyecto.
  • Mozilla analiza varios temas relacionados con seguridad web. Sus páginas también incluyen principios de seguridad que se aplican a cualquier sistema.