web-dev-qa-db-ja.com

SQLインジェクションの防止

Drupal 6では、クエリはdb_query()で発行されます。%-修飾子を使用すると、クエリ引数はフィルターされた後にクエリに代入されます。文字列%s(および文字列のみ)は最終的にmysqli_real_escape_string()を実行します( db_escape_string() を使用)。

mysqli_real_escape_string() のphpドキュメントを見ると、次のセキュリティ警告が表示されます。

文字セットは、mysqli_set_charset()に影響を与えるために、サーバーレベルで設定するか、API関数mysqli_real_escape_string()で設定する必要があります。

mysql_real_escape_string/SQLインジェクションに関する別の質問への回答 は次のように説明しています。

Mysql_real_escape_stringを使用してお湯に浸る別の方法は、間違ったメソッドを使用してデータベース接続エンコーディングを設定する場合です。これを行う必要があります:

mysql_set_charset('utf8', $link);

これを行うこともできます。

mysql_query("SET NAMES 'utf8'", $link);

問題は、後者がmysql_ APIをバイパスすることです。これにより、latin1(またはその他の何か)を使用してデータベースと通信していると見なされます。 [...]これは、特定のマルチバイト文字列状況でのインジェクション攻撃に使用できます。

Drupalはmysqli_set_charset()を呼び出さず、代わりにクエリ 'SET NAMES utf8'を発行します。これは db_connect() で確認できます。

SQLインジェクションからDrupal 6を適切に保護するために、文字セットはサーバーレベルで設定する必要がありますか?

6
rcourtna

この stackoverflow質問への回答 は、マルチバイト文字セットを使用してmysqli_real_escape_string()を回避できる攻撃を説明するのに優れています。

Drupal 6を実行するとき、しないを実行すると、サーバーレベルで文字セットを設定する必要があると結論しました攻撃から安全であるために。

Drupalは常にクライアントをUTF8に設定します(エクスプロイトに必要なGBKまたはBIG-5文字セットは設定しません)。新しいバージョンのMySQL(> 5.1)も脆弱ではありません。

ただし、Drupalはこのエクスプロイトから安全ですが、「データベースはutf8_general_ciなどのUTF-8(Unicode)エンコーディングで作成する必要があります。」というインストールドキュメントに従う必要があります。

1つの役立つコメント インストールドキュメントの概要UTF8エンコーディングでデータベースを作成する方法、およびバックアップ/復元の実行時にUTF8が使用されるようにする方法:

Mysqlコマンドラインインターフェースでこれを行うには、次のコマンドを使用します。
$ mysql -u root -p # Login
mysql> CREATE DATABASE databasename CHARACTER SET utf8; # Create with utf-8

Mysqldump/mysqlをバックアップ/復元に使用する場合は、/ etc/mysql/my.cnfに挿入して、サーバーとクライアントの両方を強制的にutf8にします。
default-character-set = utf8 # Server
skip-character-set-client-handshake # Force client

1
rcourtna