Saneamiento
La saneamiento o sanitización (sanitization) consiste en limpiar o transformar la información recibida del usuario para que no contenga caracteres peligrosos o no deseados antes de usarla en el programa.
A diferencia de la validación, que comprueba si un dato es correcto (por ejemplo, si una edad es un número entero), la sanitización busca que el dato sea seguro de utilizar (por ejemplo, eliminando etiquetas HTML o espacios innecesarios).
Los datos que llegan del usuario (por $_GET, $_POST, $_COOKIE, etc.) nunca son completamente fiables.
Un atacante podría enviar:
- Etiquetas HTML o scripts maliciosos (ataques XSS).
- Código PHP o SQL inyectado.
- Caracteres invisibles o manipulados.
Por eso, antes de guardar o mostrar los datos, hay que sanearlos para evitar riesgos de seguridad y errores de ejecución.
Métodos principales de sanitización en PHP
Las funciones que ofrece para sanear datos son las mismas que para validar datos: filter_input y filter_var (y sus respectivas versiones para arrays). Estas funciones forman parte de la extensión filter, y permiten aplicar filtros de limpieza fácilmente.
Ejemplo:
filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);
filter_var($nombre, FILTER_SANITIZE_SPECIAL_CHARS);
Este filtro convierte caracteres especiales (<, >, ", ') en entidades HTML, para evitar que se interpreten como código. Por ejemplo, < lo convierte a <, & lo convierte a &, etc.
Filtros predeterminados
FILTER_SANITIZE_EMAIL
Elimina caracteres no válidos en un email
filter_var($email, FILTER_SANITIZE_EMAIL)
FILTER_SANITIZE_URL
Quita caracteres ilegales de una URL
filter_var($url, FILTER_SANITIZE_URL)
FILTER_SANITIZE_NUMBER_INT
Elimina todo excepto dígitos y signos
filter_var($edad, FILTER_SANITIZE_NUMBER_INT)
FILTER_SANITIZE_NUMBER_FLOAT
Permite limpiar números con decimales
filter_var($precio, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)
FILTER_SANITIZE_SPECIAL_CHARS
Convierte caracteres especiales a entidades HTML.
filter_var($texto, FILTER_SANITIZE_SPECIAL_CHARS)
FILTER_SANITIZE_STRING
El filtro FILTER_SANITIZE_STRING fue eliminado a partir de PHP 8.1 por problemas de seguridad.
En su lugar, usa strip_tags() o htmlspecialchars() (ver más abajo).
Funciones nativas para sanitizar texto
Estas funciones de PHP permiten limpiar manualmente strings.
htmlspecialchars()
Convierte caracteres especiales (<, >, ", ', &) en entidades HTML.
Es la forma más segura de mostrar texto del usuario en una página web sin que se ejecute código.
$comentario = "<script>alert('XSS');</script>";
echo htmlspecialchars($comentario, ENT_QUOTES, 'UTF-8'); // <script>alert('XSS');</script>
Recomendación: usar siempre las opciones ENT_QUOTES y codificación 'UTF-8'.
strip_tags()
Elimina completamente las etiquetas HTML y PHP de un texto.
$texto = "<b>Hola</b> <i>mundo</i> <script>alert('XSS');</script>";
echo strip_tags($texto); // Hola mundo alert('XSS');
Puedes permitir etiquetas seguras pasándoselas como segundo parámetro. Por ejemplo:
echo strip_tags($texto, '<b><i>');
trim()
Elimina espacios en blanco (y saltos de línea) al inicio y al final de una cadena. Es ideal para limpiar campos de texto antes de validarlos o almacenarlos.
$nombre = trim($_POST['nombre'] ?? '');
addslashes() y mysqli_real_escape_string()
La función addslashes añade barras invertidas en un string y la función mysql_real_escape_string escapa caracteres especiales en una cadena para su uso en una sentencia SQL.
Ambas funciones son muy útiles para evitar inyecciones SQL.
$nombre = addslashes("Rock N' Roll"); // Rock N\' Roll
Actualmente se recomienda usar consultas preparadas (PDO o MySQLi), pero estos métodos siguen siendo útiles para entender el concepto.
Combinación de validación y sanitización
En muchos casos se usa una combinación de ambos procesos:
- Saneas el dato para eliminar contenido peligroso.
- Validas que el valor resultante sea correcto.
Ejemplo:
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Correo válido: $email";
} else {
echo "Correo no válido.";
}
Buenas prácticas
- Sanea siempre antes de guardar o mostrar datos. Incluso si el usuario es de confianza.
- Usa
htmlspecialchars()al mostrar contenido del usuario en HTML. - No confíes en
FILTER_SANITIZE_STRING(obsoleto desde PHP 8.1). - Combina validación y sanitización para máxima seguridad.
- Usa consultas preparadas (PDO o MySQLi) al trabajar con bases de datos.
- Mantén una codificación consistente (
UTF-8) para evitar errores con acentos y caracteres especiales.
Ejemplo completo
<form method="POST" action="procesar.php">
Nombre: <input type="text" name="nombre">
Email: <input type="email" name="email">
<button type="submit">Enviar</button>
</form>
<?php
// Sanitización
$nombre = filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
// Validación
if (empty($nombre)) {
echo "El nombre no puede estar vacío.";
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "El correo electrónico no es válido.";
}
if (!empty($nombre) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Datos seguros: $nombre ($email)";
}
?>