短い答え
正解です。
長い答え
これは正しいですが、あなたの質問は、ここで何が起こっているのかについての理解の深さが不足していることを示しています。クエリは次のとおりです。
INSERT INTO table (column, column2) VALUES ('{$escaped_value}', "0")
エスケープしないと、ユーザーが次のデータを入力するとどうなるか見てみましょう。
Eve'
文字列をMySQLに渡すだけで、挿入はPHPの文字列処理によって行われることに注意してください。これは、この場合、mysql_queryに送信されるクエリは次のとおりであることを意味します。
INSERT INTO table (column, column2) VALUES ('Eve'', "0")
これは構文エラーであり、ページエラーが発生します。さて、私のようなユーザー(つまり、あなたの一日を悲惨なものにすることに熱心な野郎)がこれらの1つを見つけたとき、私たちは遊ぶ時間だと知っています。次のデータがユーザーによって提供された場合はどうなりますか?
Eve', "0"); DROP TABLE table--
クエリは次のように拡張されます。
INSERT INTO table (column, column2) VALUES ('Eve', "0"); DROP TABLE table--', "0")
これは構文エラーではありませんが、問題があります...現在、意図していなかったクエリを実行しています。(認識できない場合、「-」はSQLのコメントを示します。つまり、「この時点以降はすべて無視します」)。
現在、これはこの正確なインスタンスでは発生しません(mysql_queryは複数のクエリをサポートしていません)が、これは防止しようとしている種類の攻撃です-SQLインジェクションとして知られる攻撃のクラスです。mysql_real_escape_stringを使用するとどうなるか見てみましょう!
入力されたデータは次のようになります。
Eve\', \"0\"); DROP TABLE table--
つまり、クエリ文字列は次のようになります。
INSERT INTO table (column, column2) VALUES ('Eve\', \"0\"); DROP TABLE table--}', "0")
どちらでもいいです!ユーザーが入力したデータは、ユーザーが入力したときにデータベースに保存されます。引用符なしではなく、余分な円記号を付けずに、入力時に追加します。これは重要です。他の方法でデータを保存すると、後でエスケープ解除またはダブルエスケープなどの問題が発生します。さらに、余分なスラッシュなどを追加すると、何らかの形でユーザーに公開されることがよくあります。これは、物事が適切に回避されていない可能性があることを示す巨大な警告サインです。あなたは間違ったことをしたくありません、そしてあなたは特に間違ったことをしたりそれについて宣伝したりすることを避けたいです、それは私を次のセクションに連れて行きます:
データをエスケープする代わりの方法
魔法の引用。あなたが指摘したように、非推奨になりました(そして正当な理由で)、避けてください。
データをエスケープしないでください。私はこのオプションに反対することをお勧めします。
入力から不正な文字を削除します。ほぼすべての状況で煩わしいので、技術的に簡単に保存できるものではなく、ユーザーが入力したものを保存する必要があります。
不正な文字の入力を禁止します。受け入れられる場合もあれば(クレジットカード番号フィールドで引用符を処理する必要がない場合)、煩わしい場合もあり、大規模な警告サインが表示される場合もあります(たとえば、パスワードフィールドの場合)。
プリペアドステートメント。文字列への変数の「入力」はPHPによって行われ、MySQLはクエリ文字列を取得しているだけなので、エスケープする必要があると言いました。プリペアドステートメントは、もう少しインテリジェントになることでこの作業をオフロードします。プリペアドステートメントを使用すると、次のようになります(警告:擬似コード)。
$ statement = $ db-> prepare('INSERT INTO table(column、column2)VALUES( "%1"、 "%2")'); $ result = $ statement-> execute($ value1、$ value2);
SQLエスケープメソッドに関する素晴らしいスタックオーバーフローの質問があり、そこでの答えはより深く掘り下げられているので、それを読むことをお勧めします。
個人的には、これは私が好きなオプションです。変数をエスケープして、この方法でデータベースに挿入することを忘れないでください。値が適切にマーシャリングされているか、データベースの近くにないため、途中のオプションはありません。つまり、すべてのクエリがプリペアドステートメントを通過し、次のような文字列の連結がないことを強制するとします。
$db->prepare('INSERT INTO table VALUES('.$value.')'))
終わらせる。私の意見では、これは、どの変数がサニタイズされ、どの変数がサニタイズされていないかを追跡するよりも簡単です。文字列がユーザーから届いたらすぐにエスケープするのが好きな人もいますが、データベース以外の場所、つまりHTMLやmemcacheなどに戻ることができれば、それは非常に厄介です。自分で行う場合は、たとえば、ハンガリアン記法を提案します。
$uValue = $_POST['value'];
$sValue = escape($uValue);
$db->query('INSERT INTO table VALUES(' . $sValue .')');
このアイデアは、JoelSpolskyによる優れた記事MakingWrong CodeLookWrongで最初に見ました。
結論
うまくいけば、今すぐ注射防止サイトを作成する準備ができていると感じます。どちらの方法を選択しても幸運を祈ります。データベースにアクセスする前に、すべてのユーザー入力を常にエスケープするようにしてください。;)