D/ DJANGO CON CRITERIO

UNIDAD 4 · SEGURIDAD Y CONSISTENCIA

Seguridad en base.py: cookies, CSRF y cabeceras

Declara las defensas comunes y comprueba qué depende de cada middleware.

Ilustración: Las defensas de cada petición
Las defensas de cada petición

CAPÍTULO 2 · Del arranque a una base protegida

La protección empieza a formar parte de la base

Con el recorrido de la petición a la vista, la seguridad deja de parecer una lista de opciones para pegar al final. Una cookie puede circular bajo ciertas condiciones; una respuesta puede autorizar o impedir que otra página la incruste. Son decisiones que afectan a la aplicación completa, incluso si la persona que crea la siguiente pantalla no piensa en ellas.

Las reunimos en base.py para que el equipo parta de una política reconocible. Conservamos los valores acordados y estudiamos uno por uno qué hacen las opciones de cookies, CSRF y cabeceras. Importa tanto conocer su propósito como su alcance: marcar una cookie HttpOnly no corrige una consulta mal autorizada, y una cabecera no reemplaza la validación de datos.

Las exigencias específicas de HTTPS tendrán su momento cuando lleguemos al servidor. Por ahora contamos con una base común que podemos explicar y verificar. SensorHub aún necesita convertirse en algo más que una página: debe representar estaciones y conservar mediciones. Esa necesidad nos lleva a preparar un lugar donde los datos puedan existir con reglas propias.

Leer esta parte dentro del relato completo →

DEL RELATO A LA PRÁCTICA

Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.

MIRA · CONECTA · COMPRENDE

Las defensas de cada petición

Las defensas de cada petición1. Petición: Entrada y contexto de confianza; 2. Middleware: Aplica los controles comunes; 3. Cookies: Define acceso y envío; 4. Respuesta: Comprueba cabeceras y contrato01PeticiónEntrada y contexto de confianza02MiddlewareAplica los controles comunes03CookiesDefine acceso y envío04RespuestaComprueba cabeceras y contrato

Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.

Selecciona una pieza para destacar su responsabilidad.

Leer la explicación del mapa
  1. Petición. Entrada y contexto de confianza
  2. Middleware. Aplica los controles comunes
  3. Cookies. Define acceso y envío
  4. Respuesta. Comprueba cabeceras y contrato
Descargar gráfico SVG ↓

¿Para qué sirve?

Separar settings por entorno no basta. La política común debe expresar cómo se envían cookies, qué acepta el navegador y qué peticiones valida el servidor.

El concepto, explicado

base.py reúne las opciones compartidas por desarrollo y producción. SecurityMiddleware emite varias cabeceras de seguridad, CsrfViewMiddleware valida las solicitudes que protege y XFrameOptionsMiddleware controla la inclusión de páginas. Declarar una variable sin el middleware o componente que la consume no activa esa defensa.

SESSION_COOKIE_HTTPONLY=True impide leer la cookie de sesión con JavaScript. Esto dificulta extraer esa cookie mediante scripts, pero un XSS todavía puede ejecutar acciones como el usuario. El escape de templates y el tratamiento de entradas no confiables siguen siendo necesarios.

SESSION_COOKIE_SAMESITE y CSRF_COOKIE_SAMESITE con Lax restringen ciertos envíos entre sitios. Su política permite navegaciones superiores seguras que suelen participar en retornos de identidad. SameSite complementa la validación CSRF; no elimina la necesidad del token ni garantiza autorización.

CSRF_COOKIE_HTTPONLY=False permite el patrón AJAX que lee csrftoken. No es obligatorio desactivar HttpOnly para todo AJAX: si lo activas, toma el token desde un input renderizado con csrf_token. HttpOnly sobre la cookie CSRF ofrece poco beneficio práctico frente a XSS. Un contrato frontend/backend coherente importa más que copiar un valor sin revisar su uso.

SESSION_COOKIE_AGE=1200 define una ventana de veinte minutos. SESSION_SAVE_EVERY_REQUEST=True renueva una sesión utilizada y guarda cada petición correspondiente. Es una expiración deslizante; no impone una duración absoluta máxima desde el login. Esa política tiene costo de escrituras y debe ajustarse al riesgo de la aplicación.

X_FRAME_OPTIONS=DENY mitiga clickjacking impidiendo que una respuesta se embeba. Si necesitas un iframe interno, una excepción SAMEORIGIN en esa vista mantiene el resto en DENY. El laboratorio de esta academia utiliza esa excepción localizada.

SECURE_CONTENT_TYPE_NOSNIFF=True indica al navegador respetar los tipos declarados. Sirve correctamente los archivos y mantén uploads no confiables separados. SECURE_REFERRER_POLICY="same-origin" reduce información enviada en Referer a otros orígenes, pero no oculta datos que tú pongas en una URL o log.

La academia pública no instala SessionMiddleware ni login. Las opciones de sesión permanecen explícitas como política, pero no crean sesiones ni protegen una API por sí solas. En un proyecto autenticado instala el middleware de sesiones antes del de autenticación.

Opciones comunes y su alcance

AjusteQué mitiga o controlaLímite importante
SESSION_COOKIE_HTTPONLYLectura de la cookie de sesión desde scriptsNo impide toda acción de un XSS
SESSION_COOKIE_SAMESITE / CSRF_COOKIE_SAMESITEAlgunos envíos de cookies entre sitiosNo sustituye tokens ni permisos
CSRF_COOKIE_HTTPONLY / NAMEContrato de lectura del tokenSi HttpOnly=True, usar token del DOM
SESSION_COOKIE_AGE / SAVE_EVERY_REQUESTDuración y renovación de sesiónNo es un límite absoluto de sesión
X_FRAME_OPTIONSClickjacking mediante embebidoRevisar widgets y excepciones
SECURE_CONTENT_TYPE_NOSNIFFInterpretación por adivinación de MIMENo valida uploads ni reemplaza escape
SECURE_REFERRER_POLICYFiltración de Referer entre orígenesNo limpia logs ni parámetros de URL

Qué hace cada ajuste

1. SESSION_COOKIE_HTTPONLY

SESSION_COOKIE_HTTPONLY = True

Para qué y por qué se usa. El navegador no permite que JavaScript lea la cookie de sesión. Esto dificulta su extracción por scripts inyectados.

Alcance y condiciones. Un XSS aún puede realizar acciones dentro de la página. Sigue escapando contenido, evitando marcado no confiable y verificando permisos.

Cómo verificarlo. En una aplicación que cree sesiones, inspecciona sessionid en las herramientas del navegador: debe tener HttpOnly.

2. CSRF_COOKIE_HTTPONLY

CSRF_COOKIE_HTTPONLY = False

Para qué y por qué se usa. El cliente AJAX puede leer csrftoken de la cookie para enviarlo como X-CSRFToken. Mantiene coherencia con ese patrón de frontend.

Alcance y condiciones. No significa desactivar CSRF. Si eliges True en otro proyecto, JavaScript puede obtener el token desde un input renderizado con csrf_token. HttpOnly en esta cookie no resuelve XSS.

Cómo verificarlo. Comprueba que el cliente obtiene el token y que un POST protegido sin token devuelve 403, mientras uno válido pasa.

3. SESSION_COOKIE_SAMESITE

SESSION_COOKIE_SAMESITE = 'Lax'

Para qué y por qué se usa. Restringe el envío de la cookie de sesión en ciertos contextos entre sitios y permite navegaciones superiores seguras que pueden participar en un retorno de login.

Alcance y condiciones. Complementa CSRF. No autoriza operaciones ni sustituye comprobar state en un retorno de identidad.

Cómo verificarlo. Inspecciona el atributo SameSite y prueba el flujo legítimo de ida y vuelta de la aplicación.

4. CSRF_COOKIE_SAMESITE

CSRF_COOKIE_SAMESITE = 'Lax'

Para qué y por qué se usa. Aplica esa política de envío a la cookie del token CSRF, alineándola con el recorrido web.

Alcance y condiciones. El token y la comprobación de origen siguen siendo necesarios para las peticiones protegidas.

Cómo verificarlo. Inspecciona csrftoken y prueba un origen permitido y otro ajeno.

5. CSRF_COOKIE_NAME

CSRF_COOKIE_NAME = 'csrftoken'

Para qué y por qué se usa. Define un nombre estable que el cliente puede buscar al construir el header X-CSRFToken.

Alcance y condiciones. El nombre no cifra ni vuelve secreto el token. Debe coincidir con lo que busca JavaScript.

Cómo verificarlo. Compara el nombre emitido en Set-Cookie y el utilizado por el cliente API.

6. X_FRAME_OPTIONS

X_FRAME_OPTIONS = 'DENY'

Para qué y por qué se usa. Impide embeber la respuesta en otro frame y mitiga clickjacking: interfaces superpuestas que engañan al usuario.

Alcance y condiciones. Bloquea también iframes legítimos del mismo sitio. Solo una vista que los necesite recibe la excepción SAMEORIGIN, como el laboratorio de esta academia.

Cómo verificarlo. Comprueba X-Frame-Options: DENY en las páginas y SAMEORIGIN únicamente en /laboratorio/.

7. SESSION_COOKIE_AGE

SESSION_COOKIE_AGE = 1200

Para qué y por qué se usa. Define una vigencia de veinte minutos para una sesión que se cree y use. Reduce el tiempo de uso de una sesión abandonada según su backend.

Alcance y condiciones. No establece por sí sola una duración absoluta desde el login. Tampoco crea sesiones en una academia que no las utiliza.

Cómo verificarlo. Inspecciona expiración/Max-Age y comprueba el vencimiento con el backend de sesión seleccionado.

8. SESSION_SAVE_EVERY_REQUEST

SESSION_SAVE_EVERY_REQUEST = True

Para qué y por qué se usa. Guarda y renueva una sesión utilizada en las peticiones correspondientes, haciendo que la ventana sea deslizante.

Alcance y condiciones. Un usuario activo puede mantenerla. Aumenta escrituras; un límite absoluto requiere lógica y política adicionales.

Cómo verificarlo. Repite una petición con sesión y comprueba que se actualiza su expiración. No confundas actividad con un nuevo login.

9. SECURE_CONTENT_TYPE_NOSNIFF

SECURE_CONTENT_TYPE_NOSNIFF = True

Para qué y por qué se usa. Emite X-Content-Type-Options: nosniff para que el navegador respete los tipos declarados en los contextos donde aplica esa política.

Alcance y condiciones. No valida uploads ni reemplaza el escape de HTML. Sirve los archivos no confiables con tipos y almacenamiento adecuados.

Cómo verificarlo. Inspecciona la cabecera en una respuesta real y verifica Content-Type de los recursos.

10. SECURE_REFERRER_POLICY

SECURE_REFERRER_POLICY = 'same-origin'

Para qué y por qué se usa. Emite Referrer-Policy: same-origin y limita la información de Referer enviada a otros orígenes.

Alcance y condiciones. No elimina datos sensibles que ya escribiste en parámetros, logs, analítica o mensajes.

Cómo verificarlo. Inspecciona Referrer-Policy y una navegación hacia un origen externo.

Implementación paso a paso

  1. Identifica los middlewares activos y sus responsabilidades.
  2. Añade las opciones compartidas al bloque de seguridad de base.py.
  3. Elige el patrón CSRF del cliente: token de cookie o token renderizado.
  4. Define el timeout y aclara si es deslizante o absoluto.
  5. Conserva DENY y documenta las excepciones de iframe necesarias.
  6. Comprueba cabeceras en una respuesta real.
  7. En la aplicación empresarial, prueba un POST protegido con y sin token y el alcance de sus permisos.

Ejemplo en SensorHub

# config/settings/base.py: política compartida
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_AGE = 1200
SESSION_SAVE_EVERY_REQUEST = True

CSRF_COOKIE_HTTPONLY = False  # si el cliente toma csrftoken de la cookie
CSRF_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_NAME = "csrftoken"

X_FRAME_OPTIONS = "DENY"
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_REFERRER_POLICY = "same-origin"

# Componentes que aplican las cabeceras y CSRF:
# django.middleware.security.SecurityMiddleware
# django.middleware.csrf.CsrfViewMiddleware
# django.middleware.clickjacking.XFrameOptionsMiddleware
# En un proyecto con sesión:
# SessionMiddleware antes de AuthenticationMiddleware.

# Excepción solo en una vista que deba admitir iframe del propio origen:
# @method_decorator(xframe_options_sameorigin, name="dispatch")
# class GameView(TemplateView): ...

Cómo leer el ejemplo

  • Las opciones son comunes a ambos entornos. Secure y HTTPS se configuran en production.py.
  • La renovación de sesión no es un bloqueo ante todo abuso; decide una duración absoluta si el dominio la requiere.
  • Una cookie CSRF legible no significa que la sesión de usuario deba ser legible.
  • La API pública de conversión no usa credenciales ni guarda estado; no sirve como prueba del contrato de una API autenticada.

Error habitual

Confundir flags de cookies con permisos de API, o creer que HttpOnly neutraliza cualquier XSS. Comprueba cada amenaza y el componente que aplica la defensa.

05 / PRACTICAR

Tu turno

El frontend lee csrftoken de document.cookie y alguien activa CSRF_COOKIE_HTTPONLY=True. Explica el fallo y dos formas coherentes de resolverlo.

Ver solución orientativa

JavaScript deja de leer esa cookie. Puedes mantenerla legible para ese contrato o cambiar el cliente para leer el token de un input renderizado por csrf_token. No quites la validación CSRF para esconder el error.

Cómo sabes que funciona

  • Las respuestas llevan nosniff, Referrer-Policy y X-Frame-Options esperados.
  • La vista de laboratorio admite solo SAMEORIGIN y las demás conservan DENY.
  • El contrato CSRF funciona con la política de cookie elegida.
  • No se añadió login a la academia.

Para profundizar

Documentación oficial para comprobar configuración, permisos y condiciones vigentes. Revisión del tema: 11 de octubre de 2026.

CONTINUAR LA EXPERIENCIA

El siguiente paso del recorrido:

PostgreSQL local y diagnóstico de conexión →Continuar en modo relato