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 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
- Petición. Entrada y contexto de confianza
- Middleware. Aplica los controles comunes
- Cookies. Define acceso y envío
- Respuesta. Comprueba cabeceras y contrato
01 / EL PROBLEMA
¿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.
02 / COMPRENDER
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
| Ajuste | Qué mitiga o controla | Límite importante |
|---|---|---|
| SESSION_COOKIE_HTTPONLY | Lectura de la cookie de sesión desde scripts | No impide toda acción de un XSS |
| SESSION_COOKIE_SAMESITE / CSRF_COOKIE_SAMESITE | Algunos envíos de cookies entre sitios | No sustituye tokens ni permisos |
| CSRF_COOKIE_HTTPONLY / NAME | Contrato de lectura del token | Si HttpOnly=True, usar token del DOM |
| SESSION_COOKIE_AGE / SAVE_EVERY_REQUEST | Duración y renovación de sesión | No es un límite absoluto de sesión |
| X_FRAME_OPTIONS | Clickjacking mediante embebido | Revisar widgets y excepciones |
| SECURE_CONTENT_TYPE_NOSNIFF | Interpretación por adivinación de MIME | No valida uploads ni reemplaza escape |
| SECURE_REFERRER_POLICY | Filtración de Referer entre orígenes | No limpia logs ni parámetros de URL |
CONFIGURACIÓN EXPLICADA OPCIÓN POR OPCIÓN
Qué hace cada ajuste
1. SESSION_COOKIE_HTTPONLY
SESSION_COOKIE_HTTPONLY = TruePara 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 = FalsePara 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 = 1200Para 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 = TruePara 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 = TruePara 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.
03 / CONSTRUIR
Implementación paso a paso
- Identifica los middlewares activos y sus responsabilidades.
- Añade las opciones compartidas al bloque de seguridad de base.py.
- Elige el patrón CSRF del cliente: token de cookie o token renderizado.
- Define el timeout y aclara si es deslizante o absoluto.
- Conserva DENY y documenta las excepciones de iframe necesarias.
- Comprueba cabeceras en una respuesta real.
- En la aplicación empresarial, prueba un POST protegido con y sin token y el alcance de sus permisos.
04 / APLICAR
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.
06 / VERIFICAR
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