La seguridad no debe ser una fase final en el desarrollo de software, sino estar integrada desde el diseño (Security by Design). Esta guía repasa las prácticas de desarrollo seguro estructuradas en base al OWASP Top 10, el estándar global de los riesgos de seguridad más críticos en aplicaciones web.
Ocurre cuando un usuario puede acceder a datos o funciones que no le corresponden. El caso más típico es el IDOR (Insecure Direct Object Reference).
// ❌ VULNERABLE: Confiar ciegamente en el ID proporcionado por el usuario
$id = $_GET['id']; // Ej: ?id=5
$q = $pdo->query("SELECT * FROM invoices WHERE id = $id");
// ✅ SEGURO: Validar la propiedad del objeto
$id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$stmt = $pdo->prepare("SELECT * FROM invoices WHERE id = ? AND owner_id = ?");
$stmt->execute([$id, $user_id]);
El almacenamiento inseguro de datos sensibles (como contraseñas o tarjetas de crédito) es fatal. Nunca uses algoritmos obsoletos como MD5 o SHA1 para contraseñas, ya que son vulnerables a ataques de diccionario y colisiones.
// ❌ VULNERABLE: Hashes rápidos sin "Salt"
$hash = md5($_POST['password']);
// ✅ SEGURO: Usar algoritmos modernos con Salt automático (Bcrypt/Argon2)
$hash = password_hash($_POST['password'], PASSWORD_DEFAULT);
// Para verificar el login:
if (password_verify($_POST['password'], $hash_en_db)) { /* Login OK */ }
Ocurre cuando datos no confiables se envían a un intérprete (SQL, OS, LDAP) como parte de un comando. Para prevenir la Inyección SQL, la única defensa 100% efectiva son las Consultas Preparadas (Prepared Statements).
// ❌ VULNERABLE: Concatenación directa
$email = $_POST['email'];
$pdo->query("SELECT * FROM users WHERE email = '" . $email . "'");
// ✅ SEGURO: Consultas preparadas (Separar código de datos)
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => $email]);
Como Ingeniero DevSecOps, te han asignado revisar el código heredado de un proyecto. Identifica las funciones nativas inseguras en PHP y aplica los parches recomendados por la industria para asegurar la compilación.
>_ INICIAR RETO CTF 09Errores arquitectónicos. Se soluciona aplicando Threat Modeling (Modelado de Amenazas) en la fase de diseño. Si una app permite infinitos intentos de login sin CAPTCHA o bloqueo, es un defecto de diseño, no un bug de código.
Dejar credenciales por defecto, servicios innecesarios activos, o mostrar trazas de error (Stack Traces) detalladas en producción.
# ❌ VULNERABLE: Mostrar errores en Producción (php.ini)
display_errors = On
# ✅ SEGURO: Loggear en archivo, no mostrar al usuario
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
Usar librerías (npm, pip, composer) con vulnerabilidades conocidas (CVEs). La mitigación consiste en implementar herramientas SCA (Software Composition Analysis) como Dependabot o Snyk en tu pipeline CI/CD.
Mala gestión de sesiones. Permite ataques de fuerza bruta, robo de sesiones o relleno de credenciales (Credential Stuffing).
session_regenerate_id(true);El código seguro moderno se audita de forma automática antes de llegar a producción mediante un Pipeline CI/CD: