2011-07-11 7 views
5

私はsprintf()がSQLインジェクションを再度保護すると聞いたことがあります。それは本当ですか?はいの場合は、それが再びSQLインジェクションを保護する方法は?sprintf()がSQLインジェクションを再び保護する方法は?

人々は、このようなクエリの書き込みを推奨している理由:任意の保護を行いません

$sql = sprintf('SELECT * FROM TABLE WHERE COL1 = %s AND COL2 = %s',$col1,$col2); 
+8

*どの人がこのようなことをお勧めしていますか? – Tomalak

+1

おそらく、別のトピックである準備文です。 – Gal

答えて

8

sprintf wont protect!私はあなたがPDOを見てみましょうsugets、それは私がDBconectionsとクエリのために使用したいものです。より安全な注射

ノートです

$sql = sprintf('SELECT * FROM TABLE WHERE COL1 = "%s" AND COL2 = "%s"', 
mysql_real_escape_string($col1), 
mysql_real_escape_string($col2)); 

を:それはあなたがそうmysql_real_escape_stringの必要があります%s

を置き換えます

8

を。 sprintfを使用すると、より読みやすいコードが作成され、各変数にmysql_real_escape_stringを実行するように文字列をドロップアンドドロップすることができます。しかし、その例では、最後に変数をエスケープしないので、利点が失われます。

適切な保護が必要な場合は、bound parametersを提供するものを使用してください。

+8

+1、 'myself_real_escape_string'は+1です。 :D – deceze

+0

Ooops。 'stupid_overlong_not_fake_function_names'は朝のこの時点で誤植を導入するのが容易ではありません。 :) – Quentin

3

sprintfを使用すると、数値フィールドのSQL注入を防ぐことができます。

$sql = sprintf("SELECT * FROM table WHERE col1 = %i", $col1); 

このようにsprintfを使用すると、$ col1が整数に変換されることが確実になります。実際には整数でない場合は、エラーまたは警告が生成される可能性があります。

SQLインジェクションから保護する適切な方法は、すべての入力値をチェックし、エスケープすることです。しかし、それは他の質問にははるかに詳しく書かれているので、ここでは詳しく説明しません。

+0

しかし整数では、とにかく特別な注意をする必要はありません。 – Tomalak

+1

確かに...ユーザー入力の "整数"がこのように見える場合はどうすればいいですか? "; DROP TABLE users;"? – Flimzy

+0

それは非常に単純な整数ではありません。私は、あなたがタイプチェックを落とすことができるとは言わなかった。 – Tomalak

1

明らかにそうではありません。本やチュートリアルで実際に読んだことがある場合は、自動的に破棄して後で参照できるようにしてください。

ただし、それ以上の処理が必要な出力を生成する実際の方法となります。比べてください:

echo '<p>Hello, <strong></strong>' . htmlspecialchars($name) . ', welcome to ' . htmlspecialchars($place). '</p>'; 

echo sprintf('<p>Hello, <strong>%s</strong>, welcome to %s</p>', 
    htmlspecialchars($name), 
    htmlspecialchars($place) 
); 

同じようなSQLコードとして、出力の他の種類に適用されるが、もちろん、あなたはまだそれを安全にするために、入力に何かをする必要があります()sprintfのは通常の文字列関数でありますそれはSQLとデータベースを認識しません。

// Fictional DB abstraction layer 
$sql = 'SELECT foo_id 
    FROM foo 
    WHERE name=:name AND status=:status'; 
$params = array(
    'name' => $name, 
    'status' => $status, 
); 
$result = $db->run($sql, $params); 

私は特に、PDO、この構文を提供し、それらのDBライブラリを、使いやすい見つける理由です:

そのバインド・パラメータは、同様の構文を使用しますのでご注意ください。

関連する問題