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 输入异常"; }
特殊文字をフィルタリングしない場合のSQLの状況を見てみましょう:
// $nameに不要なSQL文が挿入されていることを設定 $name = "Qadir'; DELETE FROM users;"; mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");
上記のインジェクション文では、$nameの変数にフィルタリングが行われていません。$nameには必要でないSQL文が挿入されており、usersテーブルのすべてのデータが削除されます。
PHPのmysqli_query()では複数のSQL文を実行することは許可されていませんが、SQLiteやPostgreSQLでは複数のSQL文を実行することができます。したがって、これらのユーザーのデータに対して厳格な検証を行う必要があります。
SQLインジェクションを防ぐために、以下のポイントに注意する必要があります:
1.ユーザーの入力を絶対に信頼しないでください。ユーザーの入力を検証し、正規表現や長さの制限を使用して、シングルクォートや 双-"を使用して変換などを行います。
2.動的SQLを構築することは絶対に避けるべきであり、パラメータ化SQLやストレージプロシージャを使用してデータのクエリや存取を行うべきです。
3.管理権限のデータベース接続を使用することは絶対に避けるべきであり、各アプリケーションに権限が制限されたデータベース接続を使用するべきです。
4.機密情報を直接保存しないでください。パスワードやその他の敏感情報を暗号化またはハッシュ化してください。
5.アプリケーションの異常情報は、可能な限り少ないヒントを提供すべきであり、カスタムエラーメッセージを使用して元のエラーメッセージを包装するのが最善です。
6.sqlインジェクションの検出方法は、一般的にサブスクライプソフトウェアやウェブプラットフォームを使用して検出されます。ソフトウェアでは、jskyなどのSQLインジェクション検出ツールを使用し、ウェブプラットフォームでは、亿思ウェブセキュリティプラットフォームの検出ツールやMDCSOFT SCANなどを使用します。MDCSOFT-IPSは効果的にSQLインジェクション、XSS攻撃などを防ぐことができます。
スクリプト言語、例えばPerlやPHPでは、ユーザー入力データをエスケープすることでSQLインジェクションを防ぐことができます。
PHPのMySQLエクステンションはmysqli_real_escape_string()関数を提供し、特殊な入力文字をエスケープします。
if (get_magic_quotes_gpc()) { $name = stripslashes($name); } $name = mysqli_real_escape_string($conn, $name); mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");
likeクエリ時に、ユーザーが入力した値に"_"と"%"がある場合、このような状況が発生します:ユーザーは本来"abcd_"をクエリしたいと思っていましたが、クエリ結果には"abcd_"、"abcde"、"abcdf"などが含まれています;ユーザーは""をクエリしたいと思っています。30%"(注:3割)の場合でも問題が発生します。
PHP スクリプトでは、addcslashes() 関数を使用して以下のような処理を行うことができます。以下に例を示します:
$sub = addcslashes(mysqli_real_escape_string($conn, "%something_"), "%_"); // $sub == \%something\_ mysqli_query($conn, "SELECT * FROM messages WHERE subject LIKE '{$sub}%';
addcslashes() 関数は指定された文字の前にアンカーサラを追加します。
構文形式:
addcslashes(string,characters)
パラメータ | 説明 |
---|---|
文字列 | 必須。チェックする文字列を指定します。 |
文字 | オプション。addcslashes() に影響を与える文字または文字範囲を指定します。 |
具体的なアプリケーションについては、以下を参照してください:PHP addcslashes() 関数