¡Detener!
Estás cometiendo un error aquí. Oh, no, ha elegido las funciones PHP correctas para que sus datos sean un poco más seguros. Esta bien. Su error está en el orden de las operaciones. , y cómo y dónde usar estas funciones.
Es importante comprender la diferencia entre desinfectar y validar datos de usuario, escapar de datos para almacenamiento y escapar de datos para presentación.
Desinfección y validación de datos de usuario
Cuando los usuarios envían datos, debe asegurarse de que hayan proporcionado algo que usted espera.
Desinfección y filtrado
Por ejemplo, si espera un número, asegúrese de que los datos enviados sean un número . También puedes enviar datos de usuario a otros tipos. Todo lo que se envía se trata inicialmente como una cadena, por lo que obligar a los datos numéricos conocidos a ser un número entero o flotante hace que la desinfección sea rápida e indolora.
¿Qué pasa con los campos de texto de forma libre y las áreas de texto? Debe asegurarse de que no haya nada inesperado en esos campos. Principalmente, debe asegurarse de que los campos que no deben tener contenido HTML no contengan HTML. Hay dos formas de lidiar con este problema.
Primero, puede intentar escapar de la entrada HTML con htmlspecialchars
. No debe usar htmlentities
para neutralizar HTML, ya que también realizará la codificación de caracteres acentuados y otros que cree que también deben codificarse.
En segundo lugar, puede intentar eliminar cualquier posible HTML. strip_tags
Es rápido y fácil, pero también descuidado. HTML Purifier hace un trabajo mucho más completo al eliminar todo el HTML y también permite una lista blanca selectiva de etiquetas y atributos.
Las versiones modernas de PHP se entregan con la extensión de filtro , que proporciona una forma integral de desinfectar la entrada del usuario.
Validación
Asegurarse de que los datos enviados estén libres de contenido inesperado es solo la mitad del trabajo. También debe intentar asegurarse de que los datos enviados contengan valores con los que realmente pueda trabajar.
Si espera un número entre 1 y 10, debe verificar ese valor. Si está utilizando una de esas nuevas entradas numéricas elegantes de la era HTML5 con un control giratorio y pasos, asegúrese de que los datos enviados estén en línea con el paso.
Si esos datos provienen de lo que debería ser un menú desplegable, asegúrese de que el valor enviado sea uno que apareció en el menú.
¿Qué pasa con las entradas de texto que satisfacen otras necesidades? Por ejemplo, las entradas de fecha deben validarse a través de strtotime
la clase DateTime . La fecha dada debe estar entre los rangos que espera. ¿Qué pasa con las direcciones de correo electrónico? La extensión de filtro mencionada anteriormente puede verificar que una dirección esté bien formada, aunque soy fanático de la biblioteca is_email .
Lo mismo es cierto para todos los demás controles de formulario. ¿Tienes botones de radio? Validar contra la lista. ¿Tienes casillas de verificación? Validar contra la lista. ¿Tienes un archivo cargado? Asegúrese de que el archivo sea del tipo esperado y trate el nombre del archivo como datos de usuario sin filtrar.
Cada navegador moderno viene con un conjunto completo de herramientas de desarrollo integradas, lo que hace que sea trivial para cualquiera manipular su formulario. ¡Su código debe suponer que el usuario ha eliminado por completo todas las restricciones del lado del cliente en el contenido del formulario !
Datos de escape para almacenamiento
Ahora que se ha asegurado de que sus datos están en el formato esperado y contienen solo los valores esperados, debe preocuparse por mantener esos datos en el almacenamiento.
Cada mecanismo de almacenamiento de datos tiene una forma específica de asegurarse de que los datos se escapen y codifiquen correctamente. Si está creando SQL, la forma aceptada de pasar datos en consultas es mediante declaraciones preparadas con marcadores de posición .
Una de las mejores formas de trabajar con la mayoría de las bases de datos SQL en PHP es la extensión PDO . Sigue el patrón común de preparar una declaración , vincular variables a la declaración y luego enviar la declaración y las variables al servidor . Si no ha trabajado con PDO antes, aquí hay un tutorial bastante bueno orientado a MySQL .
Algunas bases de datos SQL tienen sus propias extensiones especiales en PHP, incluidos SQL Server , PostgreSQL y SQLite 3 . Cada una de esas extensiones cuenta con soporte para sentencias preparadas que opera de la misma manera preparar-vincular-ejecutar que PDO. A veces es posible que necesite usar estas extensiones en lugar de PDO para admitir características o comportamientos no estándar.
MySQL también tiene sus propias extensiones PHP. Dos de ellos, de hecho. Solo quieres usar el que se llama mysqli . La antigua extensión "mysql" ha quedado en desuso y no es segura ni sana de usar en la era moderna.
Personalmente no soy fanático de mysqli. La forma en que realiza el enlace variable en las declaraciones preparadas es inflexible y puede ser difícil de usar. En caso de duda, use PDO en su lugar.
Si no está utilizando una base de datos SQL para almacenar sus datos, consulte la documentación de la interfaz de la base de datos que está utilizando para determinar cómo pasar los datos de manera segura a través de ella.
Cuando sea posible, asegúrese de que su base de datos almacene sus datos en un formato apropiado. Almacenar números en campos numéricos. Almacenar fechas en campos de fecha. Almacene dinero en un campo decimal, no en un campo de coma flotante. Revise la documentación proporcionada por su base de datos sobre cómo almacenar correctamente diferentes tipos de datos.
Datos de escape para presentación
Cada vez que muestre datos a los usuarios, debe asegurarse de que los datos se escapen de forma segura, a menos que sepa que no se deben escapar.
Al emitir HTML, casi siempre debe pasar cualquier información que fue originalmente suministrada por el usuario htmlspecialchars
. De hecho, la única vez que no debe hacer esto es cuando sabe que el usuario proporcionó HTML y sabe que ya se ha desinfectado mediante una lista blanca.
Algunas veces necesitas generar Javascript usando PHP. ¡Javascript no tiene las mismas reglas de escape que HTML! Una forma segura de proporcionar valores proporcionados por el usuario a Javascript a través de PHP es a través de json_encode
.
Y más
Hay muchos más matices para la validación de datos.
Por ejemplo, la codificación del juego de caracteres puede ser una gran trampa . Su aplicación debe seguir las prácticas descritas en " UTF-8 hasta el final ". Hay ataques hipotéticos que pueden ocurrir cuando trata los datos de cadena como el conjunto de caracteres incorrecto.
Anteriormente mencioné las herramientas de depuración del navegador. Estas herramientas también se pueden utilizar para manipular datos de cookies. Las cookies deben tratarse como entradas de usuario no confiables .
La validación y el escape de datos son solo un aspecto de la seguridad de las aplicaciones web. Debe conocer las metodologías de ataque de las aplicaciones web para poder construir defensas contra ellas.