Contents
Introducción: por qué escapar salidas en WordPress
Escapar salidas es una práctica fundamental de seguridad y calidad en cualquier tema o plugin de WordPress. Cuando muestras datos que vienen de usuarios, de la base de datos o de fuentes externas, debes transformarlos para que no contengan código ejecutable no deseado (XSS), HTML malicioso ni protocolos peligrosos en enlaces. WordPress proporciona funciones específicas para cada contexto: esc_html, esc_attr y esc_url. Cada una está diseñada para un uso concreto: contenido HTML, atributos HTML y URLs respectivamente.
Escapar vs Sanear vs Validar
Es importante distinguir tres pasos distintos:
- Validar: comprobar que los datos cumplen un formato esperado (ej. que un email tenga formato correcto).
- Saniar (sanitize): limpiar los datos al guardarlos en la base de datos. Ej.: sanitize_text_field(), sanitize_email().
- Escapar (escape): transformar datos justo antes de mostrarlos en HTML para evitar ejecución de código. Ej.: esc_html(), esc_attr(), esc_url().
Regla práctica: sanear al guardar, escapar al mostrar.
Resumen rápido de las funciones
- esc_html( text ): escapa caracteres especiales para mostrar contenido dentro del flujo HTML (entre etiquetas). Convierte < a lt y gt etc.
- esc_attr( text ): escapa cadenas para incluir en atributos HTML (value=, title=, alt=, data-, etc.).
- esc_url( url ): limpia y escapa URLs para atributos href, src, action, etc. Elimina protocolos peligrosos (como javascript:) y devuelve una URL segura o una cadena vacía si no es válida.
Cuándo usar cada una: ejemplos prácticos
1) Contenido dentro de etiquetas (esc_html)
Usa esc_html cuando vas a imprimir texto entre etiquetas HTML. Ideal para títulos, descripciones o contenido corto que no debe interpretar HTML.
lt?php title = get_the_title() // viene de la BD // Correcto: escapar antes de mostrar en el flujo HTML echo lth3gt . esc_html( title ) . lt/h3gt ?gt
Evita insertar directamente title sin escapar: si contiene ltscriptgt podrías introducir XSS.
2) Valores de atributos (esc_attr)
Para atributos como value, title, placeholder, alt o data-, utiliza esc_attr.
lt?php placeholder = get_post_meta( post->ID, _mi_placeholder, true ) ?gt ltinput type=text name=mi_input value=lt?php echo esc_attr( valor_guardado ) ?gt placeholder=lt?php echo esc_attr( placeholder ) ?gtgt
Si el atributo contiene comillas o saltos de línea, esc_attr las escapará correctamente para mantener la integridad del HTML.
3) Enlaces y URLs (esc_url)
Para href, src y cualquier URL use esc_url. Esta función además de escapar, valida protocolos seguros y normaliza la URL.
lt?php profile_url = get_user_meta( user_id, profile_url, true ) // Correcto: limpiar y escapar la URL antes de insertarla en href echo lta href=quot . esc_url( profile_url ) . quotgtPerfillt/agt ?gt
esc_url elimina protocolos como javascript: y devuelve string vacío si la URL no es segura. Para guardar URLs en la BD normalmente usarías sanitize_text_field() o esc_url_raw() al guardar esc_url es para salida.
Casos concretos y patrones comunes
Salida internacionalizada con printf/esc_html__
lt?php // Texto traducible con placeholders: escapar cada argumento según su contexto printf( esc_html__( Artículo publicado por %s el %s, mi-textdomain ), esc_html( author_name ), esc_html( publish_date ) ) ?gt
Nunca pongas cadenas traducibles sin escapar: usa las funciones esc_html__ o esc_attr__ según el contexto.
Atributos data- con contenido complejo
Para atributos data que contienen JSON o contenido con comillas, serializa y escapa con esc_attr. Si necesitas JSON seguro para JavaScript, usa wp_json_encode combinado con esc_attr o esc_js según cómo lo vayas a inyectar.
lt?php data = array( id =gt 123, name =gt OReilly ) json = wp_json_encode( data ) // codifica correctamente ?gt ltdiv data-info=lt?php echo esc_attr( json ) ?gtgtlt/divgt
srcset y múltiples URLs
Si tienes una lista de URLs (por ejemplo srcset), escapa cada URL con esc_url y luego el conjunto con esc_attr:
lt?php parts = array( esc_url( url_1 ) . 300w, esc_url( url_2 ) . 768w, ) echo ltimg src=quot . esc_url( url_1 ) . quot srcset=quot . esc_attr( implode( , , parts ) ) . quot alt=quot . esc_attr( alt ) . quotgt ?gt
Errores comunes y cómo evitarlos
- Doble escape: no escapar varias veces en la misma salida (ej. esc_html( esc_html( x ) )). Escapar una vez en el momento de salida es suficiente.
- No escapar: imprimir directamente datos del usuario o meta sin escapar expone a XSS.
- Usar la función equivocada: usar esc_url en texto plano o esc_html en atributos puede dejar caracteres sin escapar correctamente. Elije según el contexto: contenido, atributo o URL.
- Escapar al guardar: mucho cuidado en sanear para la DB versus escapar para salida. Escapar débiles al guardar puede alterar datos que necesiten HTML legítimo preferible sanear al guardar y escapar siempre al mostrar.
Funciones relacionadas útiles
- esc_html_e(), esc_attr_e(): versiones que imprimen directamente cadenas traducibles y escapadas.
- esc_html__(), esc_attr__(): devuelven la cadena traducida ya lista para escapa (usar luego con printf/echo).
- wp_kses(): si quieres permitir un conjunto limitado de etiquetas HTML, wp_kses filtra permitiendo solo etiquetas y atributos permitidos.
- esc_url_raw(): para limpiar URLs al guardar en la base de datos a diferencia de esc_url, no aplica el mismo filtrado para salida.
Ejemplos de malas prácticas y correcciones
Mal: URL sin escapar
lt?php url = get_post_meta( id, _link, true ) echo lta href=quot . url . quotgtAbrir enlacelt/agt // inseguro ?gt
Bien: usar esc_url
lt?php url = get_post_meta( id, _link, true ) echo lta href=quot . esc_url( url ) . quotgtAbrir enlacelt/agt ?gt
Mal: imprimir descripción de usuario sin escapar
lt?php bio = get_user_meta( user_id, description, true ) echo ltdiv class=quotbioquotgt . bio . lt/divgt // puede contener scripts ?gt
Bien: usar esc_html o wp_kses si se permiten etiquetas
lt?php bio = get_user_meta( user_id, description, true ) // Mostrar texto plano: echo ltdiv class=quotbioquotgt . esc_html( bio ) . lt/divgt // O si quieres permitir etiquetas limitadas: allowed = array( a =gt array( href =gt true, title =gt true ), strong =gt array(), em =gt array(), ) echo ltdiv class=quotbioquotgt . wp_kses( bio, allowed ) . lt/divgt ?gt
Checklist rápida antes de publicar salida
- ¿Es una URL? Usa esc_url para href/src.
- ¿Va dentro de un atributo HTML? Usa esc_attr.
- ¿Es texto dentro del HTML (contenido)? Usa esc_html.
- ¿Necesitas permitir algunas etiquetas HTML? Usa wp_kses con una lista blanca.
- ¿Los datos provienen de usuario? Sanitiza al guardar y siempre escapa al mostrar.
Aplicando estas reglas básicas y utilizando consistentemente esc_html, esc_attr y esc_url evitarás la mayoría de problemas de XSS y mantendrás tu tema o plugin robusto y seguro. Escapar no es opcional: es obligatorio cada vez que muestres datos que no controlas completamente.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |