94

SQL クエリに入る前に $_SESSION['username'] をエスケープする必要がありますか?を読んでいました。そして、「その起源に関係なく、SQLクエリに渡すすべての文字列をエスケープする必要があります」と述べました。今、私はこのようなことが本当に基本的であることを知っています. Google 検索で 20,000 件以上の結果が得られました。Stackoverflow だけで 20 ページの結果が得られましたが、文字列のエスケープとは何か、またはその方法を実際に説明している人は誰もいません。あくまで想定です。手伝って頂けますか?いつものようにPHPでWebアプリを作っているので学びたいです。

私は見ました: Inserting Escape CharactersJava のすべてのエスケープ文字は何ですか? , addcslashes() で文字列をエスケープできない, エスケープ文字, mysql_real_escape_string() は実際に何をしますか? , PHP で文字列から二重引用符をエスケープするにはどうすればよいですか? MySQL_real_escape_string にスラッシュが追加されていませんか? php の文字列からエスケープ シーケンスを削除します。これは怠惰ではありません。

4

3 に答える 3

150

文字列をエスケープすることは、その文字列で使用される引用符 (およびその他の文字) のあいまいさを減らすことを意味します。たとえば、文字列を定義するときは、通常、二重引用符または単一引用符で囲みます。

"Hello World."

しかし、文字列に二重引用符が含まれている場合はどうなるでしょうか?

"Hello "World.""

あいまいさがあります。インタープリターは、文字列がどこで終わるかわかりません。二重引用符を保持したい場合は、いくつかのオプションがあります。文字列を一重引用符で囲むことができます。

'Hello "World."'

または、引用符をエスケープできます。

"Hello \"World.\""

スラッシュが前にある引用符はエスケープされ、文字列の値の一部であると理解されます。

クエリに関しては、MySQL が監視する特定のキーワードがありますが、これをクエリで使用しても混乱を招くことはありません。列に「Select」という名前の値のテーブルがあり、それを選択したいとします。

SELECT select FROM myTable

ここで、クエリにいくつかのあいまいさを導入しました。クエリ内で、バックティックを使用してあいまいさを減らすことができます。

SELECT `select` FROM myTable

これにより、フィールド名を選択する際に不適切な判断を使用して導入した混乱が解消されます。

これの多くは、値を に渡すだけで処理できますmysql_real_escape_string()。以下の例では、クエリで問題が発生しないように、ユーザーが送信したデータをこの関数に渡していることがわかります。

// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            mysql_real_escape_string($user),
            mysql_real_escape_string($password));

、 、 などadd_slashes、文字列をエスケープする方法は他にもありますが、目標が安全なクエリを実行することである場合、開発者は概してor (PostgreSQL のコンテキストではor () を好むことがわかります。addcslashesquotemetamysql_real_escape_stringpg_escape_string

于 2012-05-18T03:01:43.300 に答える
23

一部の文字は、使用している SQL データベースにとって特別な意味を持ちます。これらの文字がクエリで使用されている場合、攻撃者がデータベースを危険にさらすなど、予期しない動作や意図しない動作を引き起こす可能性があります。これらの文字がこのようにクエリに影響を与えないようにするには、エスケープする必要があります。別の言い方をすれば、このクエリでこれらの文字を特殊文字として扱わないようにデータベースに指示する必要があります。

その場合、、、 、がmysql_real_escape_string()エスケープされ、これらがエスケープされていない場合、MySQL データベースでの SQL インジェクションを含む前述の問題が発生する可能性があります。\x00\n\r\'"\x1a

于 2012-05-18T03:00:59.270 に答える
1

簡単にするために、基本的にバックスラッシュ "\" が実行時のインタープリターへのコマンドであると想像できます。

たとえば、このステートメントを解釈している間:

$txt = "Hello world!";

字句解析フェーズ中 (またはステートメントを個々のトークンに分割するとき)、これらは、、、、、、、、および識別される $トークンにtxtなります。="Hello world!";

ただし、文字列内のバックスラッシュは余分なトークンのセットを引き起こし、直後の文字で何かを行うコマンドとして解釈されます。

$txt = "this \" is escaped";

次のトークンになります : $txt="this\"is escapedおよび";

インタープリターは、\トークンに続く文字に基づいて何をすべきかを既に知っています (または、事前に設定されたルートを持っています)。その"ため、文字列終了コマンドとしてではなく、文字として扱います。

于 2020-06-01T14:27:44.573 に答える