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

SQLite注入

사이트가 사용자가 웹 페이지를 통해 입력을 입력하도록 허용하고 입력 내용을 SQLite 데이터베이스에 삽입하는 경우, 이때는 SQL注入이라고 불리는 보안 문제에 직면하게 됩니다. 이 장은 이러한 상황이 발생하지 않도록 방지하고 스크립트 및 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 中仍然进行堆叠查询,即执行在一个字符串中提供的所有查询,这会导致严重的安全问题。

防止 SQL 注入

在脚本语言中,比如 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}');

데이터 삽입을 안전하게 만드는 코드는 있지만, 그것은 간단한 텍스트 비교만을 제공하며, 쿼리에서 바이너리 데이터를 포함한 열에 대해 사용할 때는,LIKE 문은 사용할 수 없습니다.

addslashes()는 SQLite 쿼리에서 문자열을 인용하는 데 사용되지 않아야 합니다. 그렇지 않으면 데이터를 검색할 때 이상한 결과가 발생할 수 있습니다.