English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Se o seu site permitir que os usuários entrem por meio de uma página da web e insiram o conteúdo de entrada no banco de dados SQLite, neste momento você está enfrentando um problema de segurança chamado injecção SQL. Este capítulo explicará como evitar esse tipo de situação, garantindo a segurança do script e das instruções SQLite.
注入通常在请求用户输入时发生,比如需要用户输入姓名,但用户却输入了一个 SQLite 语句,而这语句就会在不知不觉中在数据库上运行。
永远不要相信用户提供的数据,所以只处理通过验证的数据,这项规则是通过模式匹配来完成的。在下面的实例中,用户名 username 被限制为字母数字字符或者下划线,长度必须在 8 到 20 个字符之间 - 请根据需要修改这些规则。
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){ $db = new SQLiteDatabase('filename'); $result = @$db->query("SELECT * FROM users WHERE username = $matches[0]");} else { echo "username not accepted";}
为了演示问题,请看以下摘录-
$name = "Qadir'; DELETE FROM users;";@$db->query("SELECT * FROM users WHERE username = '{$name}');
函数调用是为了从用户表中检索 name 列与用户指定的名称相匹配的记录。正常情况下,$name 只包含字母数字字符或者空格,比如字符串 ilia。但在这里,向 $name 追加了一个全新的查询,这个对数据库的调用将会造成灾难性的问题:注入的 DELETE 查询会删除 users 的所有记录。
尽管已经存在不允许查询堆叠或在单个函数调用中执行多个查询的数据库接口,如果尝试堆叠查询,则会调用失败,但 SQLite 和 PostgreSQL 仍然进行堆叠查询,即执行在一个字符串中提供的所有查询,这会导致严重的安全问题。
在脚本语言中,比如 PERL 和 PHP,您可以巧妙地处理所有的转义字符。编程语言 PHP 提供了字符串函数 SQLite3::escapeString($string) 和 sqlite_escape_string() 来转义对于 SQLite 来说比较特殊的输入字符。
注意:使用函数 sqlite_escape_string() 的 PHP 版本要求为 PHP 5 < 5.4.0。
更高版本 PHP 5 >= 5.3.0, PHP 7 使用以上函数:
if (get_magic_quotes_gpc()) { $name = sqlite_escape_string($name); } $result = @$db->query("SELECT * FROM users WHERE username = '{$name}');
Embora o código faça a inserção de dados segura, ele apresentará comparações de texto simples, na consulta, para colunas que contêm dados binários,LIKE A cláusula não está disponível.
Atenção, addslashes() não deve ser usado em consultas SQLite para citar strings, ele causará resultados estranhos ao recuperar dados.