SQLiteインジェクション
サイトでユーザーが Web ページから入力し、入力コンテンツを 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 クエリにより、ユーザーのすべてのレコードが削除されます。
クエリのスタックや 1 つの関数呼び出しでの複数のクエリの実行を許可しないデータベース インターフェイスはすでに存在しますが、クエリをスタックしようとすると呼び出しは失敗しますが、SQLite と PostgreSQL は引き続きスタックされたクエリを実行します。文字列内 すべてのクエリは で提供されており、これは重大なセキュリティ問題につながる可能性があります。
SQL インジェクションの防止
PERL や PHP などのスクリプト言語では、すべてのエスケープ文字を賢く処理できます。プログラミング言語 PHP は、SQLite に特有の入力文字をエスケープするための文字列関数 sqlite_escape_string() を提供します。
if (get_magic_quotes_gpc()) { $name = sqlite_escape_string($name); } $result = @$db->query("SELECT * FROM users WHERE username='{$name}'");
エンコーディングによりデータの挿入が安全になりますが、バイナリ データを含む列に対して LIKE 句が使用できないクエリでは単純なテキスト比較がレンダリングされます。
SQLite クエリで文字列を引用符で囲むために addslashes() を使用しないでください。データを取得するときに奇妙な結果が生じる可能性があることに注意してください。