TLS y los riesgos comunes
Entiende qué promete una conexión cifrada, mantén encendidas sus comprobaciones y usa una lista compartida de riesgos comunes para revisar un diseño.
AL TERMINAR, PODRÁS
- Decir qué garantiza TLS y qué le deja a la aplicación
- Mantener encendida la verificación del certificado y del nombre, y detectar el código que la apaga
- Usar el OWASP Top 10 como mapa para revisar un servicio
Descripción del diagrama: Cliente → api.relay.example (TLS: privado, inalterado); Atacante en medio → Cliente; api.relay.example → Autorización; api.relay.example → Datos guardados
Qué promete TLS
TLS (Transport Layer Security, seguridad de la capa de transporte) es el protocolo que hay debajo de HTTPS y de la mayoría de las conexiones a bases de datos y a proveedores de correo.
Su especificación, la RFC 8446 para TLS 1.3, le da al canal tres propiedades. Autenticación: el servidor siempre demuestra quién es, y el cliente también puede hacerlo. Confidencialidad: solo los dos extremos pueden leer lo que se envía.
Integridad: un atacante no puede cambiar los datos sin que se note. El servidor demuestra su identidad con un certificado, que asocia un nombre como api.relay.example a una clave pública y está firmado por una autoridad de certificación en la que el cliente ya confía; durante el handshake (el saludo inicial), el servidor muestra que tiene la clave privada correspondiente. TLS protege los datos mientras viajan, y nada más.
No protege la copia que queda en tu base de datos ni en tus logs, no decide si el usuario autenticado puede cancelar ese trabajo y no oculta que hubo una conexión con tu servidor.
La verificación es lo que se apaga
Cifrar sin verificar solo cifra hacia quien conteste.
Si el cliente acepta cualquier certificado, un atacante en el camino de la red puede presentar el suyo, leerlo todo y reenviarlo. ssl.create_default_context() de Python carga las autoridades de certificación en las que confía el sistema y activa la validación del certificado y la comprobación del nombre del servidor; desde Python 3.10 también exige TLS 1.2 o posterior. En cambio, un contexto creado llamando directamente al constructor SSLContext puede no verificar nada. La verificación suele apagarse con prisa: verify=False en un cliente HTTP, CERT_NONE o check_hostname en False, agregados para pasar un error de certificado en un entorno de pruebas y que luego llegan a producción.
Corrige la causa: dale al cliente la autoridad de certificación de ese entorno con cafile y deja las comprobaciones encendidas. Busca esas cadenas en cada revisión. Para un servicio que usan navegadores, envía además la cabecera Strict-Transport-Security, que les indica usar solo HTTPS con tu sitio durante el tiempo que declara.
import ssl
import urllib.request
context = ssl.create_default_context() # trusted CAs, certificate and hostname checks
with urllib.request.urlopen("https://example.com", context=context) as response:
print(response.status)
# A test environment with its own certificate authority: trust it, keep the checks.
staging = ssl.create_default_context(cafile="staging-ca.pem")
Un mapa de riesgos comunes
OWASP, una comunidad abierta de seguridad de aplicaciones, publica el OWASP Top 10, una lista de riesgos comunes de las aplicaciones web; la edición vigente es la de 2025.
Léelo como un mapa que te devuelve a lo que ya sabes. A01, control de acceso roto (Broken Access Control): la comprobación de dueño de la lección sobre fronteras de confianza. A02, configuración insegura (Security Misconfiguration): verificación apagada, páginas de depuración encendidas, contraseñas por defecto.
A03, fallas en la cadena de suministro de software (Software Supply Chain Failures): dependencias que nunca revisaste. A04, fallas criptográficas (Cryptographic Failures): hashes de contraseña rápidos, TLS sin verificar. A05, inyección (Injection): SQL armado formateando strings en lugar de enlazar parámetros.
A06, diseño inseguro (Insecure Design): riesgos que ningún modelo de amenazas buscó. A07, fallas de autenticación (Authentication Failures): contraseñas mal guardadas y un inicio de sesión débil. A08, fallas de integridad del software o de los datos (Software or Data Integrity Failures): confiar en código o datos cuyo origen nunca se comprobó.
A09, fallas de registro y alertas (Security Logging and Alerting Failures): ataques que nadie ve. A10, mal manejo de condiciones excepcionales (Mishandling of Exceptional Conditions): errores que dejan el sistema abierto en lugar de cerrado. Una lista corta no puede cubrirlo todo, pero pasar un diseño por ella atrapa los errores habituales.
ERROR FRECUENTE
Apagar la verificación del certificado para pasar un error en un entorno de pruebas y luego publicarlo así. El tráfico sigue cifrado, pero hacia quien conteste.
INTÉNTALO TÚ
Busca en Relay, o en otro código que conozcas, verify=False, CERT_NONE, check_hostname = False y direcciones http://. Para cada resultado, di quién podría ponerse en medio y cuál es la corrección. Luego pasa el diseño de Relay por las diez categorías de OWASP y anota un riesgo para cada una.
Decide en el laboratorio.
El checkpoint de dos preguntas, tus notas y tu progreso guardado están en el laboratorio. Gratis y sin cuenta.
Abrir en el laboratorio ↗CONÉCTALO CON RELAY
Sirve la API de Relay por HTTPS con un certificado, envía Strict-Transport-Security y haz que cada llamada saliente (la base de datos, el proveedor de correo) use un contexto TLS que verifique. Agrega a la revisión de código una comprobación de verify=False y sus parientes, y escribe el recorrido de Relay por el OWASP Top 10 en su modelo de amenazas.