14

SQL インジェクションの回避について学んでいますが、少し混乱しています。

bind_param を使用する場合、目的がわかりません。マニュアルページで、次の例を見つけました。

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

さて、これら 4 つの変数がユーザー入力であると仮定すると、これがどのように SQL インジェクションを防ぐのか理解できません。私の理解では、彼らはそこに好きなものを入力することができます。

そこの説明も見つかりません'sssd'。それは何をするためのものか?それがそれをより安全にするものですか?

最後の質問:mysqli_real_escape_string非推奨の別の質問を読みましたが、マニュアルには記載されていません。それはどのように非推奨ですか?何らかの理由で特殊文字をエスケープできなくなりましたか?

注: この質問は bind_param が何をするかを説明しましたが、なぜそれがより安全であるか、より保護されているかはまだわかりません。 Bind_param の説明

4

2 に答える 2

14

準備済みステートメントを使用することで、ユーザーが入力したデータから SQL クエリを分離しています。入力データの代わりに、プレースホルダー ('?' 文字) を SQL クエリに入れます。次に、「mysqli::prepare」メソッドを使用してクエリを DBMS サーバー (例: MySQL) に送信します。したがって、サーバーはすべてが正常であることを確認し、正常であれば入力データを待ちます。今では、すでにクエリを認識しています。入力データがクエリにバインドされるのを待つだけです。

この時点で、「bind_param」が機能し、ユーザーが入力したデータにプレースホルダーをバインドします。bind_param はクエリを変更せずにデータをプレースホルダーにバインドするだけであることに注意してください。そのため、元の SQL クエリを変更する方法はありません。なぜなら、それは既に prepare メソッドによってサーバーに送信されており、SQL クエリと入力データを別々に送信しているため、ユーザーが入力したデータがクエリに干渉できないからです。

とりあえず...

SQL で準備済みステートメントを使用する実際の目的は、クエリからデータを分離することではなく、クエリの処理コストを削減することです。それが現在の使用方法であり、そもそも使用するように設計された方法ではありません.

'sssd' は、"string"、"string"、"string"、および "double" を表します。実際: $code は文字列、$language は文字列、$official は文字列、$percent は double 型です。

mysqli_real_escape_string は非推奨ではありませんが、mysql_real_escape_string は非推奨です (最初のものは mysqlI で、I は「改善された」を表します)。

于 2014-01-07T19:12:52.453 に答える