with texto strip_tags remove limpiar from eliminar allow all php mysql security

php - texto - string strip_tags



Saneamiento eficiente del texto ingresado por el usuario (3)

Hay dos cosas simples que debe hacer para estar seguro:

  • Use declaraciones preparadas o escape los datos correctamente.
  • Al enviar a HTML, siempre escapa usando htmlspecialchars ().

Tengo un formulario html que acepta texto de tamaño de entrada del usuario de alrededor de 1000, y se envía a una página php donde se almacenará en la base de datos mysql. Uso PDO con declaraciones preparadas para evitar la inyección de sql. Pero para sanitizar el texto ingresado por el usuario, ¿cuáles son los mejores esfuerzos que se deben hacer?

Quiero evitar cualquier inyección de script, ataques xss, etc.


La seguridad es un concepto interesante y atrae a mucha gente. Desafortunadamente es un tema complejo e incluso los profesionales lo malinterpretan. He encontrado agujeros de seguridad en Google (CSRF), Facebook (más CSRF), varios minoristas en línea importantes (principalmente inyección SQL / XSS), así como miles de sitios más pequeños, tanto corporativos como personales.

Estas son mis recomendaciones:

1) Usar consultas parametrizadas
Las consultas parametrizadas obligan a los valores pasados ​​a la consulta a tratarse como datos separados, de modo que el DBMS no pueda analizar los valores de entrada como código SQL. Mucha gente te recomendará escapar de tus cadenas usando mysql_real_escape_string() , pero, contrariamente a la creencia popular, no es una solución general para la inyección de SQL. Tome esta consulta por ejemplo:

SELECT * FROM users WHERE userID = $_GET[''userid'']

Si $_GET[''userid''] está establecido en 1 OR 1=1 , no hay caracteres especiales y no se filtrará. Esto da como resultado que se devuelvan todas las filas. O, lo que es peor, ¿qué 1 OR is_admin = 1 si se establece en 1 OR is_admin = 1 ?

Las consultas parametrizadas evitan que ocurra este tipo de inyección.

2) Valide sus entradas
Las consultas parametrizadas son geniales, pero a veces los valores inesperados pueden causar problemas con su código. Asegúrese de estar validando que están dentro del alcance y de que no permitirán que el usuario actual modifique algo que no debería poder.

Por ejemplo, puede tener un formulario de cambio de contraseña que envíe una solicitud POST a un script que cambie su contraseña. Si coloca su ID de usuario como una variable oculta en el formulario, podrían cambiarla. Enviar id=123 vez de id=321 puede significar que cambian la contraseña de otra persona. Asegúrese de que TODO esté validado correctamente, en términos de tipo, rango y acceso.

3) Use htmlspecialchars para escapar de la entrada de usuario mostrada
Digamos que su usuario ingresa su "acerca de mí" como algo como esto:
</div><script>document.alert(''hello!'');</script><div>
El problema con esto es que su salida contendrá marcado que el usuario ingresó. Tratar de filtrar esto con listas negras es solo una mala idea. Use htmlspecialchars para filtrar las cadenas de modo que las etiquetas HTML se conviertan en entidades HTML.

4) No use $ _REQUEST
Los ataques de falsificación de solicitudes entre sitios (CSRF) funcionan haciendo que el usuario haga clic en un enlace o visite una URL que representa un script que realiza una acción en un sitio para el que está conectado. La variable $_REQUEST es una combinación de $_GET , $_POST y $_COOKIE , lo que significa que no puede distinguir entre una variable que se envió en una solicitud POST (es decir, a través de una etiqueta de input en su formulario) o una variable que se configuró en su URL como parte de una GET (por ejemplo, page.php?id=1 ).

Digamos que el usuario quiere enviar un mensaje privado a alguien. Podrían enviar una solicitud POST a sendmessage.php , con to , subject y message como parámetros. Ahora imaginemos que alguien envía una solicitud GET en su lugar:

sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!

Si está usando $_POST , no verá ninguno de esos parámetros, ya que están configurados en $_GET en $_GET lugar. Su código no verá $_POST[''to''] ni ninguna de las otras variables, por lo que no enviará el mensaje. Sin embargo, si usa $_REQUEST , $_GET y $_POST $_GET unidos, por lo que un atacante puede establecer esos parámetros como parte de la URL. Cuando el usuario visita esa URL, inadvertidamente envían el mensaje. La parte realmente preocupante es que el usuario no tiene que hacer nada. Si el atacante crea una página maliciosa, podría contener un iframe que apunta a la URL. Ejemplo:

<iframe src="http://yoursite.com/sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!"> </iframe>

Esto da como resultado que el usuario envíe mensajes a personas sin siquiera darse cuenta de que hicieron algo. Por esta razón, debe evitar $_REQUEST y usar $_POST y $_GET en $_GET lugar.

5) Trate todo lo que le den como sospechoso (o incluso malicioso)
No tienes idea de lo que el usuario te está enviando. Podría ser legítimo Podría ser un ataque. Nunca confíes en nada que un usuario te haya enviado. Convierta a tipos correctos, valide las entradas, use listas blancas para filtrar cuando sea necesario (evite listas negras). Esto incluye todo lo enviado a través de $_GET , $_POST , $_COOKIE y $_FILES .



Si sigues estas pautas, estás en una posición razonable en términos de seguridad.


Debe distinguir entre dos tipos de ataques: inyección SQL y XSS. La inyección SQL se puede evitar mediante el uso de declaraciones preparadas o las funciones de presupuesto de su biblioteca de bases de datos. Utiliza la función de cita esto antes de insertar en la base de datos.

XSS se puede evitar citando todos los caracteres especiales con htmlspecialchars . Se considera un buen estilo para escapar de la salida después de leerla desde la base de datos y almacenar la entrada original en la base de datos. De esta manera, cuando utiliza la entrada en otros contextos donde no se necesita escaparse de HTML (correo electrónico de texto, cadena codificada JSON), todavía tiene la entrada original del usuario.

También vea esta respuesta a una pregunta similar.