protegerse - ¿Cómo prevenir los ataques de inyección de código en PHP?
inyeccion sql login (8)
mysql_real_escape_string
utilizado cuando se inserta en la base de datoshtmlentities()
utilizado al generar datos en la página webhtmlspecialchars()
usado cuando?strip_tags()
usado cuando?addslashes()
usado cuando?
htmlspecialchars () usado cuando?
htmlspecialchars
es más o menos lo mismo que htmlentities
. La diferencia: codificaciones de caracteres.
Ambos codifican caracteres de control como <
, >
, etc., utilizados para abrir etiquetas, etc. Las htmlentities
también codifican caracteres de otros lenguajes como umlauts, euro-symbols y otros. Si sus sitios web son UTF, use htmlspecialchars()
; de lo contrario, use htmlentities()
.
strip_tags () usado cuando?
htmlspecialchars
/ entities
codifican los caracteres especiales, por lo que se muestran pero no se interpretan . strip_tags
ELIMINA.
En la práctica, depende de lo que necesita hacer.
Un ejemplo: has codificado un foro y les das a los usuarios un campo de texto para que puedan publicar cosas. Los maliciosos solo intentan:
pictures of <a href="javascript:void(window.setInterval(function () {window.open(''http://evil.com'');}, 1000));">kittens</a> here
Si no hace nada, se mostrará el enlace y una víctima que haga clic en el enlace recibe muchas ventanas emergentes.
Si htmlentity / htmlspecialchar su salida, el texto estará allí tal como está. Si lo strip_tag, simplemente elimina las etiquetas y lo muestra:
pictures of kittens here
A veces puede querer una mezcla, deje algunas etiquetas allí, como <b>
( strip_tags
puede dejar ciertas etiquetas allí). Esto tampoco es seguro, por lo tanto, es mejor utilizar una biblioteca totalmente desarrollada contra XSS.
agregalas
Para citar una versión anterior del manual de PHP :
Devuelve una cadena con barras diagonales inversas antes de los caracteres que deben citarse en las consultas de la base de datos, etc. Estos caracteres son comillas simples (''), comillas dobles ("), barras invertidas () y NUL (el byte NULO ).
Un uso de ejemplo de addslashes () es cuando ingresas datos en una base de datos. Por ejemplo, para insertar el nombre O''reilly en una base de datos, deberá escapar de él. Se recomienda encarecidamente utilizar la función de escape específica de DBMS (por ejemplo, mysqli_real_escape_string () para MySQL o pg_escape_string () para PostgreSQL), pero si el DBMS que está utilizando no tiene una función de escape y el DBMS usa / para escapar de caracteres especiales, usted puede usar esta función.
La versión actual está redactada de manera diferente.
Estoy un tanto confuso, hay tantas funciones en PHP, y algunas usan esto, algunas usan eso. Algunas personas usan: htmlspecialchars()
, htmlentities()
, strip_tags()
etc.
¿Cuál es la correcta y qué usas normalmente?
¿Es correcto (avisarme uno mejor, si hay alguno):
$var = mysql_real_escape_string(htmlentities($_POST[''username'']));
Esta línea puede evitar la inyección de MySQL y XSS attact ??
Por cierto, ¿hay otras cosas que deba prestar atención además del ataque XSS y la inyección de MySQL?
EDITAR
Para concluir:
Si quiero insertar cadena en la base de datos, no necesito usar htmlentities
, simplemente use mysql_real_escape_string
. Al mostrar los datos, use htmlentities()
, ¿es eso lo que todos ustedes quieren decir?
Resumir:
-
mysql_real_escape_string
utilizado cuando se inserta en la base de datos -
htmlentities()
utilizado al generar datos en la página web -
htmlspecialchars()
usado cuando? -
strip_tags()
usado cuando? -
addslashes()
usado cuando?
¿Alguien puede completar el signo de interrogación?
Eche un vistazo a este sitio PHP Security Consortium . Descubrí que es un buen sitio para obtener una visión global de la seguridad de PHP (incluye SQL Injection y XSS).
No utilizaría htmlentities () al insertar datos en la base de datos o consultar la base de datos. Si los datos en su base de datos se almacenan como entidades, esos datos solo son útiles para algo que entienda entidades html.
htmlentities() usar diferentes mecanismos de escape para diferentes tipos de resultados, por ejemplo, SQL - mysql_real_escape_string() , HTML - htmlentities() o htmlspecialchars() , shell - escapeshellarg() . Esto se debe a que los caracteres que son "peligrosos" son diferentes para cada uno; no existe una forma mágica de que pueda proteger cualquier información para cualquier medio de salida.
Pensé en esta rápida lista de verificación:
- Siempre use HTTPS, sin HTTPS su sitio está totalmente descifrado . Y no, cifrar cosas en el lado del cliente y enviarlas no funcionará, piénselo. Los certificados HTTPS no válidos también lo hacen vulnerable a un ataque MITM . Simplemente use Let''s Encrypt si no puede pagar un certificado.
- Siempre use
htmlspecialchars()
en cualquier salida de su código PHP, es decir, o contiene una entrada de usuario . La mayoría de los motores de plantillas te ayudan a hacerlo fácilmente. - Use bandera HTTP-only en su
php.ini
para evitar que las secuencias de comandos accedan a sus cookies - Prevenir problemas relacionados con la sesión
- Nunca exponga el
PHPSESSID
del usuario (ID de sesión) fuera de la cookie , si alguien conoce una ID de sesión de otra persona, simplemente puede usarla para iniciar sesión en su cuenta. - Tenga mucho cuidado con la función
Remember me
, muestre una pequeña advertencia tal vez. - Actualizar la ID de la sesión cuando el usuario inicia sesión (o lo que corresponda)
- Tiempo de espera de sesiones inactivas
- Nunca exponga el
- Nunca confíe en una cookie, puede ser modificada, eliminada, modificada y creada por un script / usuario en cualquier momento
- Prevenir problemas relacionados con SQL
- Siempre use declaraciones preparadas . Las sentencias preparadas hacen que la entrada del usuario se pase por separado y previene la inyección de SQL.
- Haz que tu código arroje una excepción cuando falla. A veces, su servidor SQL puede estar inactivo por alguna razón, las bibliotecas como
PDO
ignoran ese error de manera predeterminada y registran una advertencia en los registros. Esto hace que las variables que obtiene del DB sean nulas, dependiendo de su código, esto puede causar un problema de seguridad. - Algunas bibliotecas como
PDO
emulan las declaraciones preparadas. Apaga eso. - Use la
UTF-8
en sus bases de datos, le permite almacenar virtualmente cualquier carácter y evitar los ataques relacionados con la codificación - Nunca concatene nada con su consulta . Cosas como
$myquery = "INSERT INTO mydb.mytable (title) VALUES(" . $user_input . ")"
Significa que tienes un gran riesgo de seguridad de una inyección SQL.
- Almacene los archivos cargados en nombres de archivo aleatorios y sin extensión. Si un usuario carga un archivo con la extensión de archivo
.php
, cada vez que el código carga ese archivo, lo ejecuta y permite al usuario ejecutar algún código de back-end. - Asegúrate de no ser vulnerable a un ataque CSRF .
- Actualice siempre su copia de PHP para garantizar los últimos parches de seguridad y mejoras de rendimiento
Sé que es una vieja pregunta, pero hoy en día la respuesta más votada puede ser engañosa para los principiantes.
A partir de 2017
Nunca deberías usar mysql_real_escape_string. Incluso mysqli_real_escape_string es demasiado débil para proteger su base de datos de las inyecciones de SQL. En lugar de esto, debe usar PDO y técnicas similares. (mira esa guía )
XSS (aquí quiero decir:
strip_tags()
,addslashes()
,htmlspecialchars()
,htmlentities()
) - aquí la respuesta más votada sigue siendo correcta, pero sugiero leer este artículo
Solo codifique los datos en el punto en el que va a codificarse en el sistema; de lo contrario, se encontrará con situaciones en las que desea manipular los datos reales.
Para la inyección SQL, use variables vinculadas tal como se describe en ¿Cómo puedo evitar la inyección SQL en PHP? (habla sobre declaraciones preparadas, pero es la unión lo que le brinda protección, no la preparación).
Para XSS: si está escribiendo en HTML en el punto donde se especifica HTML o texto. Use htmlentities en el punto donde genera su documento. Evitaría almacenar los datos en esa forma en la base de datos (excepto en un sistema write-rare-read-often donde el rendimiento de la CPU / los tiempos de acceso al disco se estaban convirtiendo y emitiendo) y luego tendría una versión raw_ y una html_ de la columna ... o simplemente usa memcached o similar).
Si está permitiendo que los usuarios ingresen URL, debe tener más cuidado, ya que javascript:do_evil()
es un URI válido que se ejecutará (por ejemplo, como href para un enlace clicado o (en algunos navegadores) el src de una imagen que solo está cargado).
Solo necesita usar mysql_escape_string () cuando inserta en una base de datos y htmlentites cuando muestra el HTML. Esto es suficiente si desea evitar un ataque de inyección simple, pero no hay duda de que hay muchos otros problemas de seguridad que debe tener en cuenta al desarrollar una aplicación web, otro de los principales es la falsificación de solicitudes entre sitios.
htmlspecialchars()
convierte &
, ''
, "
, <
y >
en un formato de entidad HTML ( &
"
, etc.)
htmlentities()
convierte todos los caracteres aplicables en su formato de entidad HTML.
strip_tags()
elimina todas las etiquetas HTML y PHP.
Ambos htmlspecialchars()
y htmlentities()
toman un parámetro opcional que indica cómo se deben manejar las comillas. Ver el manual de PHP para detalles.
La función strip_tags()
toma un parámetro opcional que indica qué etiquetas no deben eliminarse.
$var = strip_tags ($var, ''<p><br />'');
La función strip_tags()
eliminará incluso las etiquetas HTML no válidas, lo que puede causar problemas. Por ejemplo, strip_tags()
eliminará todo el código que crea que es una etiqueta HTML, incluso si está incorrectamente formado, como
<b I forgot to close the tag.