データベースに接続せずにmysql_real_escape_stringとして動作する関数を使用したいのですが、DB接続なしでドライテストを実行する必要がある場合があります。mysql_escape_stringは非推奨であるため、望ましくありません。私の発見のいくつか:
http://www.gamedev.net/community/forums/topic.asp?topic_id=448909
データベースに接続せずにmysql_real_escape_stringとして動作する関数を使用したいのですが、DB接続なしでドライテストを実行する必要がある場合があります。mysql_escape_stringは非推奨であるため、望ましくありません。私の発見のいくつか:
http://www.gamedev.net/community/forums/topic.asp?topic_id=448909
回答:
DB接続なしで文字列を安全にエスケープすることは不可能です。mysql_real_escape_string()
準備されたステートメントは、適切な文字セットを使用して文字列をエスケープできるように、データベースへの接続が必要です。そうでない場合でも、マルチバイト文字を使用してSQLインジェクション攻撃が可能です。
テストのみを行う場合は、mysql_escape_string()
SQLインジェクション攻撃に対して100%保証されるわけではありませんが、DB接続なしで安全なものを構築することは不可能です。
mysql_escape_string
接続なしで使用します(まだ理由を理解しようとしています)。その関数は廃止されているので、どうすればそれを置き換えることができるのかと思っています。接続を開かずに "適切な文字セット"を置き換える関数でそれを指定できることは確かに理にかなっているようです。
mysql_real_escape_string関数のリファレンスページによると、「mysql_real_escape_string()は、MySQLのライブラリ関数mysql_real_escape_stringを呼び出します。これは、\ x00、\ n、\ r、\、 '、 "、および\ x1aをエスケープします。」
それを念頭に置いて、投稿した2番目のリンクで提供される関数は、必要な機能を正確に実行する必要があります。
function mres($value)
{
$search = array("\\", "\x00", "\n", "\r", "'", '"', "\x1a");
$replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z");
return str_replace($search, $replace, $value);
}
mb_strpos()
(およびとmb_substr()
同様の動作を作成してsubstr_replace()
)安全ですか?
私の他の答えに直接反対すると、この以下の関数は、マルチバイト文字を使用しても、おそらく安全です。
// replace any non-ascii character with its hex code.
function escape($value) {
$return = '';
for($i = 0; $i < strlen($value); ++$i) {
$char = $value[$i];
$ord = ord($char);
if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
$return .= $char;
else
$return .= '\\x' . dechex($ord);
}
return $return;
}
上記のコードが機能しない理由を、私自身よりも知識のある誰かに教えてもらいたい...
さらなる研究から、私は見つけました:
http://dev.mysql.com/doc/refman/5.1/en/news-5-1-11.html
SQLインジェクションのセキュリティホールがマルチバイトエンコーディング処理で発見されました。バグはサーバーにあり、mysql_real_escape_string()C API関数でエスケープされた文字列を誤って解析していました。
この脆弱性は、OSDBコンソーシアムのプロジェクト間セキュリティコラボレーションの一環として、Josh BerkusとTom Laneによって発見および報告されました。SQLインジェクションの詳細については、次のテキストを参照してください。
討論。SQLインジェクションのセキュリティホールがマルチバイトエンコーディング処理で見つかりました。SQLインジェクションのセキュリティホールには、ユーザーがデータベースに挿入するデータを提供したときに、サーバーが実行するデータにSQLステートメントを挿入する場合があります。この脆弱性に関して、文字セットを認識しないエスケープが使用されている場合(たとえば、PHPのaddlashes())、一部のマルチバイト文字セット(SJIS、BIG5、GBKなど)でエスケープをバイパスすることが可能です。その結果、addslashes()などの関数はSQLインジェクション攻撃を防ぐことができません。サーバー側でこれを修正することは不可能です。最善の解決策は、アプリケーションがmysql_real_escape_string()などの関数によって提供される文字セット対応のエスケープを使用することです。
ただし、MySQLサーバーがmysql_real_escape_string()の出力を解析する方法にバグが検出されました。その結果、文字セット対応関数mysql_real_escape_string()を使用した場合でも、SQLインジェクションが可能でした。このバグは修正されました。
回避策。MySQLをmysql_real_escape_string()解析のバグの修正を含むバージョンにアップグレードできないが、MySQL 5.0.1以降を実行している場合は、回避策としてNO_BACKSLASH_ESCAPES SQLモードを使用できます。(このモードはMySQL 5.0.1で導入されました。)NO_BACKSLASH_ESCAPESは、SQL標準互換モードを有効にします。このモードでは、バックスラッシュは特殊文字とは見なされません。その結果、クエリは失敗します。
現在の接続にこのモードを設定するには、次のSQLステートメントを入力します。
SET sql_mode='NO_BACKSLASH_ESCAPES';
すべてのクライアントに対してモードをグローバルに設定することもできます。
SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';
このSQLモードは、サーバーの起動時にコマンドラインオプション--sql-mode = NO_BACKSLASH_ESCAPESを使用するか、サーバーオプションファイル(たとえば、my.cnfやmy.iniなど)にsql-mode = NO_BACKSLASH_ESCAPESを設定することで自動的に有効にすることもできます。 、システムによって異なります)。(Bug#8378、CVE-2006-2753)
Bug#8303も参照してください。
NO_BACKSLASH_ESCAPES
他の脆弱性をもたらすことに注意してください。