Contents
Introducción: sanitizar vs validar
En WordPress la seguridad y la integridad de los datos dependen en gran medida de dos procesos complementarios: sanitización (limpiar los datos) y validación (comprobar que los datos cumplen unas reglas). Sanitizar elimina o filtra caracteres peligrosos o no deseados validar verifica que el dato tiene el formato, rango o contenido esperado. Ambos pasos son imprescindibles antes de guardar, procesar o mostrar datos procedentes de usuarios, APIs externas o fuentes no confiables.
Principios y buenas prácticas
- Siempre sanitizar datos recepcionados (POST, GET, JSON, REST, etc.).
- Validar según el tipo y uso: número, email, URL, slug, color, lista, HTML permitido, etc.
- Sanitizar al recibir y escapar al mostrar. No confundir sanitizar (preparar los datos) con escaping (preparar la salida). Para escapar se usan funciones como esc_html, esc_attr, esc_url.
- Usar las utilidades nativas de WordPress cuando existan: sanitize_text_field, sanitize_email, sanitize_textarea_field, sanitize_key, wp_kses, is_email, etc.
- Proteger formularios con nonces y verificar permisos (capabilities) antes de procesar datos.
- Para SQL use siempre wpdb->prepare o la abstracción de WP para evitar inyección SQL.
Resumen rápido de funciones comunes
| Función | Uso | Salida esperada |
| sanitize_text_field | Texto plano corto | Quita etiquetas, control chars, espacios extremos |
| sanitize_textarea_field | Textos multilínea | Similar a sanitize_text_field pero conserva saltos de línea |
| sanitize_email | Emails | Filtra y normaliza email |
| sanitize_key | Claves/keys (slugs) | Lowercase, alfanum y guiones bajos |
| esc_html / esc_attr | Escapar para HTML o atributos | Convertir entidades para prevenir XSS |
| wp_kses / wp_kses_post | Permitir HTML seguro | Filtra etiquetas/atributos no permitidos |
| is_email | Validar correo | Boolean |
| absint / intval / floatval | Convertir a números | Enteros o float |
Ejemplo práctico: procesar un formulario POST
Ejemplo paso a paso que muestra verificación de nonce, capacidades, sanitización, validación y guardado.
120 ) {
errores[] = La edad debe estar entre 1 y 120.
}
if ( ! empty( errores ) ) {
// manejar errores (mostrar, redirigir, etc.)
} else {
// 5. Guardar de forma segura (opción ejemplo)
opciones = array(
nombre => nombre,
email => email,
descripcion => descripcion,
edad => edad,
)
update_option( mi_plugin_opciones, opciones )
}
}
?>
sanitize_text_field y cuándo usarla
sanitize_text_field es la función más habitual para limpiar cadenas de texto cortas: quita etiquetas HTML, control characters y limita espacios en blanco. Es ideal para nombres, títulos, slugs user-facing (aunque para slugs mejor sanitize_title o sanitize_key si lo que buscas es una clave). No es adecuada si necesitas permitir HTML seguro en ese caso usar wp_kses con una lista blanca de etiquetas permitidas.
Otras funciones de sanitización y validación
- sanitize_textarea_field: conserva saltos de línea, apropiada para descripciones o textareas.
- sanitize_email is_email: sanitize_email limpia, is_email valida si el email es correcto.
- sanitize_key: útil para slugs o claves internas (solo caracteres seguros).
- sanitize_hex_color: sanitiza colores hex (devuelve string válido o empty).
- wp_kses / wp_kses_post: permite HTML seguro según whitelist.
- esc_html, esc_attr, esc_url: escapado para salida en HTML, atributos y URLs respectivamente.
- absint, intval, floatval: conversión numérica simple.
- filter_var con FILTER_VALIDATE_INT, FILTER_VALIDATE_EMAIL, etc.: alternativa PHP pura para validaciones específicas.
Ejemplos de sanitización avanzada
Sanitizar arrays (ej. opciones con lista)
Permitir HTML seguro con wp_kses
array(
href => true,
title => true,
rel => true,
),
strong => array(),
em => array(),
br => array(),
p => array(),
)
raw_html = _POST[contenido]
clean_html = wp_kses( raw_html, allowed )
?>
Sanitizar y validar en la REST API
Cuando registras campos o rutas en la REST API debes definir callbacks de sanitización y validación: sanitize_callback y validate_callback.
POST,
callback => mi_plugin_handler,
permission_callback => function() {
return current_user_can( edit_posts )
},
args => array(
titulo => array(
required => true,
sanitize_callback => sanitize_text_field,
validate_callback => function( param, request, key ) {
return is_string( param ) mb_strlen( param ) <= 200
},
),
email => array(
required => false,
sanitize_callback => sanitize_email,
validate_callback => is_email,
),
),
) )
?>
Settings API: register_setting con callback de sanitización
Al usar settings API, proveer un callback sanitize_callback que limpie y valide todas las opciones antes de guardar.
mi_plugin_sanitize_opciones,
) )
function mi_plugin_sanitize_opciones( input ) {
output = array()
if ( isset( input[titulo] ) ) {
output[titulo] = sanitize_text_field( input[titulo] )
}
if ( isset( input[email] ) ) {
email = sanitize_email( input[email] )
if ( is_email( email ) ) {
output[email] = email
} else {
add_settings_error( mi_plugin_opciones, email_invalido, Email no válido )
}
}
return output
}
?>
Protección contra XSS y inyección
- Sanitiza inputs y escapa salidas. No dependas únicamente de sanitización al almacenar.
- Para HTML permitido, usa wp_kses con whitelist limitada.
- Para SQL usa wpdb->prepare o funciones de WordPress que internamente preparan la consulta.
query(
wpdb->prepare(
INSERT INTO {wpdb->prefix}mi_tabla (nombre, email) VALUES (%s, %s),
nombre,
email
)
)
?>
Validaciones frecuentes y ejemplos de regex
- Email: usar is_email() además de sanitize_email().
- URL: validar con filter_var(url, FILTER_VALIDATE_URL) y escapar con esc_url() al mostrar.
- Teléfono: definir un patrón permitido, por ejemplo números y , espacios, paréntesis y guiones.
Ejemplo: sanitizar entrada con HTML limitado y luego escapar atributos
Cuando se acepta HTML limitado para un campo, sanitizar con wp_kses y luego escapar al mostrar en atributos.
