Desinfección de datos: mejores prácticas con ejemplos de código

15

Estoy tratando de comprender la desinfección de datos (no la validación de datos) para ayudarme a escribir temas seguros para WordPress. He buscado en Internet tratando de encontrar una guía completa para desarrolladores de temas que detalle las mejores prácticas. Encontré un par de recursos, incluida la página del códice titulada Validación de datos, aunque ninguno me fue útil. La página del códice enumera las funciones de desinfección disponibles, su uso y lo que hacen, pero no explica por qué usaría una sobre la otra o en qué situación usaría una función de desinfección particular. El propósito de esta publicación es solicitar a todos que contribuyan con ejemplos de código incorrecto / no desinfectado y cómo deben reescribirse para una correcta desinfección. Este podría ser un código general para desinfectar el título de la publicación o la publicación thumnails src o códigos más elaborados que manejen la desinfección de$_POST datos para solicitudes de Ajax.

Además, me gustaría saber si las funciones de WordPress para agregar / actualizar la base de datos (por ejemplo, las mencionadas en el bloque de código a continuación) se encargan automáticamente del trabajo de desinfección por usted. En caso afirmativo, ¿hay alguna excepción cuando tomaría medidas adicionales para desinfectar los datos enviados a estas funciones de WordPress?

add_user_meta
update_user_meta
add_post_meta
update_post_meta
//just to name a few

Además, ¿la desinfección debe hacerse de manera diferente cuando se hace eco de HTML en PHP en comparación con PHP en línea de HTML? Para ser más claro de lo que estoy preguntando, aquí está el código:

<?php echo '<div class="some-div ' . $another_class . '" data-id="' . $id . '" >' . $text . '</div>'; ?>

<div class="some-div <?php echo $another_class; ?>" data-id="<?php echo $id; ?>"><?php echo $text; ?></div>

Ambas declaraciones anteriores logran lo mismo. ¿Pero necesitan ser santificados de manera diferente?

John
fuente
1
Podría ayudar si supiéramos lo que estaba tratando de desinfectar. Los temas son para presentar datos ... solo necesita desinfectar los datos que el usuario le envía, y los envíos generalmente se manejan mediante complementos.
EAMann
@EAMann La función de escape como esc_attr, esc_html, etc., está diseñada para escapar de la salida. Corrígeme si estoy equivocado. La presentación de datos significa que está generando datos, por lo que también se requiere escapar dentro de los temas. De lo contrario, no habría habido necesidad de las funciones esc. Quiero entender la desinfección en los temas de WordPress como un todo y no se limita a la desinfección de uno o dos fragmentos de código.
John
"Presentar datos significa que está generando datos, por lo que también se requiere escapar dentro de los temas" - no. Una vez más, solo tiene que escapar de datos en los que no confía
onetrickpony
@OneTrickPony Se está volviendo más claro para mí. Solo para estar absolutamente seguro de que entiendo esto: escaparía del contenido del comentario pero no escaparía de la ID del comentario o la ID de la publicación, si tuviera que generarlos en HTML. Lo siento, realmente molestarte con preguntas una tras otra.
John
2
"Solo tienes que escapar de datos en los que no confías" - Estoy completamente de acuerdo. Lo único que agregaría es que nunca debes confiar en los datos;)
Ian Dunn

Respuestas:

12

Esta página del códice explica bastante bien, creo.

La función más importante y comúnmente utilizada es probablemente esc_attr. Toma este ejemplo:

<a href="<?php print $author_url; ?>" title="<?php print $author_name; ?>"> 
  <?php print $author_name; ?>
</a>

Si $author_namecontiene un "personaje, cierra su atributo, y si ese personaje es seguido poronclick="do_something();" él podría empeorar :)

Haciendo print esc_attr($author_name) garantiza que dichos caracteres estén codificados y que el navegador no haga cosas que no debe hacer.

Hay un caso en el que no lo necesita: cuando espera un número, en cuyo caso puede convertir los datos de entrada a entero, por ejemplo:

print (int)$_POST['some_number'];


Las funciones meta * que enumeró allí ya se encargan de desinfectar la entrada para el almacenamiento de la base de datos, por lo que no necesita preocuparse por eso.

El wpdb->prepare()método debe usarse cuando realiza las consultas de base de datos usted mismo. Aquí hay un ejemplo:

$sql = $wpdb->prepare('
    UPDATE wp_posts SET post_title = %s WHERE ID = %d', 
      $_POST['title'], $_POST['id']);

$wpdb->query($sql);

Las palabras clave %sy %dse reemplazarán con sus valores desinfectados de $ _POST.

Un error muy común que veo en muchos complementos en el repositorio de WP.org es pasarle una consulta ya preparada (y mal preparada), como:

$wpdb->prepare('UPDATE wp_posts SET post_title = \''.$_POST['title'].' WHERE ...

No hagas esto :)

Además, ¿la desinfección debe hacerse de manera diferente cuando se hace eco de HTML en PHP en comparación con PHP en línea de HTML?

Ambas declaraciones anteriores logran lo mismo. ¿Pero necesitan ser santificados de manera diferente?

No.

Pony de un solo truco
fuente
Gracias por sus entradas. Tu explicación me aclara las cosas.
John
Se necesita una pequeña aclaración adicional. Si paso una cadena a una var (por ejemplo, $ var = 'cadena';) dentro de PHP y la echo como un atributo HTML, desinfecto $ var cuando hago eco. O solo se requiere desinfección si extraje el valor de $ var de la base de datos.
John
Al hacer eco en la pantalla, de una forma u otra
onetrickpony
Entonces, si te entendí correctamente, ya sea que pasé la cadena a $ var dentro del código PHP o extraje datos de la base de datos y pasé a $ var, ambos requieren que esclite la salida. ¿Correcto?
John
Sí, si esos datos provienen de la entrada del usuario, como por ejemplo el nombre del autor de un comentario. Si por "pasó la cadena a $ var dentro del código PHP" quiere decir que asignó un valor que conoce a una variable, entonces obviamente, no, no tiene que desinfectar esa variable
onetrickpony