Lección 6 de 6 — Cómo escribir código seguro desde el diseño hasta el despliegue.
Nunca confíes en la entrada del usuario. Toda entrada externa debe ser validada y sanitizada antes de procesarse.
Verificar que el dato cumple con el formato esperado antes de usarlo.
❌ Incorrecto
# PHP - Sin validación $id = $_GET['id']; $query = "SELECT * FROM usuarios WHERE id = $id";
✅ Correcto
# PHP - Validación estricta
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id < 1) {
die("ID inválido");
}
$query = "SELECT * FROM usuarios WHERE id = ?";
Eliminar o escapar caracteres peligrosos según el contexto de salida.
# Python - Sanitización para HTML (contra XSS)
import html
user_input = "<script>alert('XSS')</script>"
safe_output = html.escape(user_input, quote=True)
# Resultado: <script>alert('XSS')</script>
# JavaScript - Sanitización
const safe = DOMPurify.sanitize(userInput);
Nunca almacenes contraseñas en texto plano ni uses algoritmos rápidos como MD5/SHA-1. Usa funciones diseñadas para hash de contraseñas.
$2b$10$[salt][hash].# Node.js con bcrypt
const bcrypt = require('bcrypt');
const saltRounds = 12;
async function registrar(password) {
const hash = await bcrypt.hash(password, saltRounds);
// Guarda 'hash' en la base de datos
return hash;
}
async function verificar(password, hashAlmacenado) {
const match = await bcrypt.compare(password, hashAlmacenado);
return match; // true o false
}
# Python con bcrypt
import bcrypt
password = b"MiContraseñaSegura123"
salt = bcrypt.gensalt(rounds=12)
hash = bcrypt.hashpw(password, salt)
# Verificar
bcrypt.checkpw(password, hash) # True
Los logs son esenciales para detectar y responder a incidentes, pero mal manejados pueden exponer información sensible.
# Python - Logging seguro
import logging
import json
logger = logging.getLogger("seguridad")
handler = logging.FileHandler("/var/log/app/audit.log")
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
# Bueno: registrar intento sin datos sensibles
logger.warning(f"Intento de login fallido - usuario: {username} - IP: {ip}")
# Malo: exponer la contraseña en logs
logger.error(f"Login fallido - usuario: {username} - password: {password}") # ❌
OWASP proporciona guías de referencia rápida (Cheat Sheets) para las prácticas de seguridad más importantes.
| Cheat Sheet | Descripción |
|---|---|
| SQL Injection Prevention | Prepared statements, parametrización, escapes. |
| XSS Prevention | Output encoding, Content Security Policy (CSP). |
| Password Storage | bcrypt, Argon2, salt, pepper. |
| Authentication | MFA, sesiones seguras, rate limiting. |
| Input Validation | Whitelist vs blacklist, tipos de datos, rangos. |
| Content Security Policy | Cabecera CSP para mitigar XSS. |
| Logging | Qué y cómo registrar eventos de seguridad. |
npm audit, pip audit, Dependabot.🎓 La seguridad es un proceso, no un producto. Sigue aprendiendo y mejorando.