English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

SQL Injection e MySQL

如果您通过网页获取用户输入的数据并将其插入一个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 输入异常";
}

Vamos ver o que acontece sem filtrar caracteres especiais, a situação do SQL:

// Definir a inserção de instruções SQL não desejadas no $name
$name = "Qadir'; DELETE FROM users;";
 mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}');

Nos comandos de injeção acima, não filtramos a variável $name, a variável $name inseriu instruções SQL não desejadas, que excluirão todos os dados da tabela users.

Em PHP, mysqli_query() não permite a execução de várias instruções SQL, mas no SQLite e PostgreSQL é possível executar várias instruções SQL ao mesmo tempo, então precisamos verificar estritamente esses dados do usuário.

Para evitar a injeção de SQL, devemos prestar atenção aos seguintes pontos:

  • 1.Nunca confie na entrada do usuário. Verifique a entrada do usuário, pode usar expressões regulares ou limitar o comprimento; para aspas simples e Duplo "-"para conversão etc.

  • 2.Nunca use SQL montado dinamicamente, você pode usar SQL parametrizado ou usar procedimentos armazenados diretamente para consultas de dados.

  • 3.Nunca use conexões de banco de dados com privilégios de administrador, use conexões de banco de dados com privilégios limitados para cada aplicativo.

  • 4.Não armazene informações confidenciais diretamente, encripte ou faça hash das senhas e informações sensíveis.

  • 5.As informações de exceção da aplicação devem fornecer o menor número possível de sugestões, é melhor usar mensagens de erro personalizadas para embalar informações de erro originais

  • 6.Os métodos de detecção de injeção de SQL geralmente utilizam software auxiliar ou plataformas de site para detectar, o software geralmente utiliza ferramentas de detecção de injeção de SQL jsky, e plataformas de site têm ferramentas de segurança de site Yisi, MDCSOFT SCAN e outros. Utilize MDCSOFT-O IPS pode se defender eficazmente contra injeções de SQL, ataques XSS e outros.

Prevenção de injeção de SQL

Em linguagens de script, como Perl e PHP, você pode escapar os dados de entrada do usuário para evitar injeção de SQL.

A extensão MySQL do PHP oferece a função mysqli_real_escape_string() para escapar caracteres de entrada especiais.

if (get_magic_quotes_gpc()) 
{
  $name = stripslashes($name);
}
$name = mysqli_real_escape_string($conn, $name);
 mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}');

Injeção de SQL na cláusula LIKE

Ao usar a consulta 'like', se o valor introduzido pelo usuário contiver "_" e "%", ocorrerá o seguinte problema: o usuário originalmente desejava consultar "abcd_", mas o resultado da consulta inclui "abcd_", "abcde", "abcdf" e outros; o usuário deseja consultar"30%" (Nota: trinta por cento) também pode causar problemas.

Podemos usar a função addcslashes() em scripts PHP para lidar com essas situações, conforme o exemplo a seguir:

$sub = addcslashes(mysqli_real_escape_string($conn, "%something_"), "%_");
// $sub == \%something\_
 mysqli_query($conn, "SELECT * FROM messages WHERE subject LIKE '{$sub}%';

A função addcslashes() adiciona barras invertidas antes dos caracteres especificados.

Formato de Sintaxe:

addcslashes(string,characters)
ParâmetrosDescrição
stringObrigatório. Especifica a string a ser verificada.
caracteresOpcional. Especifica os caracteres ou intervalo de caracteres afetados pelo addcslashes().

Veja aplicações específicas aqui:Função addcslashes() PHP