English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题。
本章节将为大家介绍如何防止SQL注入,并通过脚本来过滤SQL中注入的字符。
所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。
以下示例中,输入的用户名必须为字母、数字及下划线的组合,且用户名长度为 8 到 20 个字符之间:
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) { $result = mysqli_query($conn, "SELECT * FROM users WHERE username=$matches[0]"); } else { echo "username 输入异常"; }
Veamos cuál es la situación de SQL cuando no se filtran los caracteres especiales:
// Configuración de $name que ha insertado instrucciones SQL no deseadas $name = "Qadir'; DELETE FROM users;"; mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}');
En las instrucciones de inyección anteriores, no hemos filtrado la variable $name, $name ha insertado instrucciones SQL no deseadas que eliminarán todos los datos de la tabla users.
En PHP, mysqli_query() no permite ejecutar múltiples instrucciones SQL, pero en SQLite y PostgreSQL es posible ejecutar múltiples instrucciones SQL simultáneamente, por lo que necesitamos verificar estrictamente estos datos de los usuarios.
Para prevenir la inyección de SQL, debemos prestar atención a los siguientes puntos:
1.Nunca confíe en la entrada del usuario. Verifique la entrada del usuario, puede hacerlo a través de expresiones regulares o limitando la longitud; para comillas simples y Dobles comillas-"para la conversión, etc.
2.Nunca utilice la construcción dinámica de SQL, puede usar SQL parametrizado o procedimientos almacenados directamente para la consulta y almacenamiento de datos.
3.Nunca utilice conexiones de bases de datos con permisos de administrador, utilice conexiones de bases de datos con permisos limitados para cada aplicación.
4.No almacenar información sensible directamente, encriptar o hashear contraseñas y otros datos sensibles.
5.La información de excepción de la aplicación debe proporcionar lo menos posible de sugerencias, mejor usar mensajes de error personalizados para envolver la información de error original
6.Los métodos de detección de inyección de SQL generalmente utilizan software auxiliar o plataformas de sitio web para detectar, el software generalmente utiliza herramientas de detección de inyección de SQL como jsky, y las plataformas de sitio web incluyen herramientas de detección de seguridad de sitio web Yisi, MDCSOFT SCAN, etc. Utilizando MDCSOFT-IPS puede defender eficazmente contra la inyección de SQL, XSS y otros ataques.
En los lenguajes de script, como Perl y PHP, puedes escapar los datos de entrada del usuario para evitar la inyección de SQL.
La extensión MySQL de PHP proporciona la función mysqli_real_escape_string() para escapar caracteres de entrada especiales.
if (get_magic_quotes_gpc()) { $name = stripslashes($name); } $name = mysqli_real_escape_string($conn, $name); mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}');
Cuando se realiza una búsqueda como 'like', si el valor introducido por el usuario contiene "_" y "%", se presentará este caso: el usuario quería buscar "abcd_", pero los resultados de la búsqueda incluyen "abcd_", "abcde", "abcdf" y otros; el usuario debe buscar"30%" (Nota: el 30%) también causará problemas.}
En los scripts PHP podemos usar la función addcslashes() para manejar este tipo de situaciones, como se muestra en el siguiente ejemplo:
$sub = addcslashes(mysqli_real_escape_string($conn, "%something_"), "%_"); // $sub == %something_"; mysqli_query($conn, "SELECT * FROM messages WHERE subject LIKE '{$sub}%';
La función addcslashes() agrega un contrabarra delante de los caracteres especificados.
Formato de sintaxis:
addcslashes(cadena, caracteres)
Parámetros | Descripción |
---|---|
cadena | Obligatorio. Especificar la cadena a verificar. |
caracteres | Opcional. Especificar los caracteres o rango de caracteres afectados por addcslashes(). |
Aplicaciones específicas pueden verse aquí:Función addcslashes() de PHP