¿En qué contextos son los complementos responsables de la validación / desinfección de datos?

17

Quiero asegurarme de que todos los datos de mis complementos / temas se manejen de forma segura antes de ingresar a la base de datos y antes de enviarlos al navegador. Mi problema es que hay situaciones en las que la API maneja la desinfección por usted, como al guardar metacampos de publicación, y otras en las que el autor del complemento / tema es totalmente responsable de hacerlo, como al guardar configuraciones personalizadas.

Para el alcance de esta pregunta, no me preocupa la validación de datos a nivel de dominio, por ejemplo, verificar que un campo Edad en un formulario esté entre 0 y 120, o que una dirección de correo electrónico sea válida. Solo me preocupa la seguridad, por ejemplo, escapar de las consultas SQL para evitar la inyección de SQL al guardar en la base de datos o desinfectar los datos que se envían a las plantillas HTML para evitar XSS.

Para la desinfección de salida, sé que siempre debe usar funciones como esc_html()y esc_attr()al hacer eco de variables en plantillas HTML. Pero, ¿qué pasa cuando se usan etiquetas de plantilla ? ¿Ya desinfectan todos los resultados? Si es así, ¿para qué contexto (HTML general, atributos de etiqueta, etc.)? Algunas funciones tienen variantes para diferentes contextos (como the_title_attribute(), pero la mayoría no.

Para la desinfección de entrada, sé que necesito usarlo $wpdb->prepare()al hacer consultas manuales, pero ¿qué pasa con el uso de la API de configuración para crear una página de configuración del complemento o al guardar metacampos de publicación para un tipo de publicación personalizado?

En este momento, he estado investigando Core y leyendo tutoriales cada vez que uso una función para averiguar si se desinfecta o no, pero es propenso a errores y consume mucho tiempo. Espero encontrar algún tipo de lista completa de todas las situaciones posibles y si la API lo maneja o no. p.ej,

API valida / desinfecta

  • Guardar meta meta con update_postmeta()
  • Guardar meta del usuario con update_user_meta()
  • Salida del título de una publicación: use la variante contextualmente apropiada de the_title()
  • etc.

Tienes que validar / desinfectar manualmente

  • Guardar opciones de complementos con la API de configuración. Pase una devolución de llamada como el tercer parámetro de register_setting().
  • Consultas directas a la base de datos: envuelva la consulta $wpdb->prepare().
  • Salida de variables en HTML. Uso esc_attr(), esc_html(), etc.
  • etc.

También me interesaría entender por qué la API lo proporciona en ciertas situaciones, pero no en otras. Supongo que tiene algo que ver con la naturaleza desconocida de los datos, pero me encantaría escuchar una explicación detallada.

Ian Dunn
fuente
Me gusta esta pregunta Tengo el mismo pensamiento que tú. Creo que si hay una lista de cuándo debemos validar / desinfectar manualmente, sería genial. +1.
Anh Tran
1
@Rilwis, mira mi respuesta. Siempre debes validar. La sanitización es más complicada, ya que "seguro" depende del contexto. En general, si usa la API de WordPress con datos conocidos de WordPress ( the_title(), the_permalink()etc.) está bien, pero con datos personalizados no lo está (por ejemplo get_post_meta()). En caso de duda, desinféctese , no puede doler.
Stephen Harris
@StephenHarris: leí tu comentario. Yo también lo sé. Pero tengo la misma opinión que Ian Dunn. Creo que la razón principal por la que pregunta es "haz lo suficiente, no más, no menos".
Anh Tran
1
De hecho, no me importa equivocarme por el lado de la precaución y hacer demasiada validación / saneamiento, pero creo que hay casos en los que escapar de las cosas dos veces puede ser un problema.
Ian Dunn

Respuestas:

15

Aquí hay dos conceptos:

  • validación: asegurarse de que los datos sean válidos , es decir, un número entero es un número entero, una fecha es una fecha (en el formato correcto, etc.). Esto debe hacerse justo antes de guardar los datos.
  • desinfección : hacer que la fecha sea segura para su uso en el contexto actual (por ejemplo, escapar de consultas SQL o escapar de HTML en la salida).

La validación es, casi universalmente, exclusivamente de usted . Sabes qué datos le estás pidiendo a un usuario, y sabes qué datos estás esperando; WordPress no. La validación se realizaría, por ejemplo, en el save_postgancho antes de guardarla en la base de datos update_post_meta, o podría hacerse mediante la especificación de una función de devolución de llamada en la API de configuración, llamada justo antes de que WordPress guarde los datos.

La sanitización es un poco más mixta. Cuando se trata de datos que WordPress conoce de forma nativa (por ejemplo, el mosaico de una publicación), puede estar seguro de que WordPress ya ha protegido los datos. Sin embargo, 'seguro' depende del contexto; lo que es seguro para usar en una página, no es necesariamente seguro como un atributo de elemento. Por lo tanto WordPress tendrá diferentes funciones para diferentes contextos (por ejemplo the_title(), the_title_rss(), the_title_attribute()) - por lo que es necesario utilizar el más adecuado .

En su mayor parte, su complemento puede tratar meta meta, o tal vez datos de eventos de una tabla personalizada. WordPress no sabe qué es esta información o para qué sirve, por lo que ciertamente no sabe cómo hacerla segura. Esto depende de ti . Esto es particularmente importante en el uso esc_url(), esc_attr(), esc_textarea()etc para evitar la entrada maliciosa de ser capaz de código de inserción. Dado que WordPress sabe que next_posts()se supone que debe imprimir una url en la página, se aplica esc_url(), pero con una meta de publicación, por ejemplo, no sabe que almacena una url, o lo que desea hacer con ella (si se imprime esc_url(), si se redirige esc_url_raw(). Si está en dobut - erre por precaución y escape usted mismo - y hágalo lo más tarde posible.

Finalmente, ¿qué hay de guardar datos? ¿Necesitas hacerla segura entonces? Como se mencionó , debe asegurarse de que los datos sean válidos. Pero si usa la API de WordPress ( wp_insert_post(), update_post_meta()etc.), entonces no necesita desinfectar los datos, porque al guardar los datos, lo único que debe hacer es escapar de las declaraciones SQL, y WordPress hace esto. Si está ejecutando instrucciones SQL directas (por ejemplo, leer / escribir datos de una tabla personalizada), debe usar la $wpdbclase para ayudarlo a desinfectar sus consultas.

Escribí esta publicación de blog sobre sanitización y validación de datos que puede encontrar útil; en ella hablo sobre lo que se espera de usted a este respecto.

Stephen Harris
fuente
Hola Stephan, gracias por la explicación. Eso me ayudó a entenderlo un poco mejor, pero lo que realmente estoy buscando es una especie de lista completa, como el ejemplo que di. Parece que su enfoque es hacer una suposición educada sobre si WP lo maneja o no, o errar por precaución y siempre desinfectar. Me sentiría más seguro si tuviera una lista completa y autorizada, en lugar de confiar en mi comprensión. También me preocupa que el doble escape pueda generar problemas.
Ian Dunn
También acabo de actualizar la pregunta para aclarar algunas cosas.
Ian Dunn
0

No estoy seguro de que sea tan exhaustivo, pero con cualquier complemento o tema, la entrada del usuario debe desinfectarse. Las operaciones de la base de datos deben realizarse utilizando los métodos $ wpdb->. Todos los datos $ _GET y $ _POST deben desinfectarse.

Esta es una mejor práctica para la programación PHP que WordPress.

Entonces, en conclusión, si hay una función de WordPress, úsela, si no, desinfecte sus variables y entradas usted mismo.

Si era demasiado vago, por favor haga una pregunta más específica.

Ciprian
fuente
3
Entiendo que siempre debe desinfectarse, pero la pregunta es sobre quién realiza la desinfección en cada situación particular. A veces WordPress lo hace automáticamente, y a veces tienes que hacerlo manualmente. He actualizado la pregunta para intentar aclararla.
Ian Dunn
Incluso cuando use update_user_meta (), aún necesita validarlo, ya que los valores actualizados pueden provenir de un formulario expuesto o de la entrada de un usuario. Si se trata de un valor proveniente de un script, como una decisión interna, de un bucle if / else, entonces no debe desinfectarlo.
Ciprian
1
El valor que se pasa a update_user_meta()se pasa a través de stripslashes_deep()y sanitize_meta()en update_metadata(), y luego $wpdb->prepare()en $wpdb->update(). Entonces, no creo que necesites desinfectarlo. ¿Me estoy perdiendo de algo?
Ian Dunn