web-dev-qa-db-ja.com

ユーザー入力をエスケープするタイミング

ユーザー入力のエスケープを処理する最良の方法はいつですか。

2つのオプションが思い浮かびます

1)ユーザーがサーバーにデータを送信し、それをエスケープしてデータベースに格納します2)データをそのまま格納し、ユーザーにデータを送信するときにエスケープします。

私にとっては、エスケープしてデータベースにデータを保存する方がはるかに簡単だと思われますが、誰かが私たちのWebサイトでフローを見つけ、エスケープを回避できたとすると、データベースに保存したすべてのデータをエスケープせずに見つけるという問題が発生します。

一方、データをそのまま保存し、ユーザーに送信したらエスケープする場合、誰かが私たちのウェブサイトでフローを見つけたとしても、システムはデータベースに保存されたデータがエスケープされていないことを前提としているため、バグを修正するだけです。

2番目のアプローチは簡単に思えますが、エラーが発生しやすくなります。サーバー上でHTMLを生成してユーザーに送信し、コンテンツをajax経由でユーザーに送信するだけに切り替えるとすると、ユーザーに送信したり、新しいAPIを実装したりする前に、すべてのデータをエスケープする必要があることを忘れがちです。第三。

それで、これを処理する好ましい方法は何ですか?

5
D.L

ユーザー入力は文字列です。 エスケープは、いくつかの文字をHTML/SQLに挿入したいときに行われます/一部の文字を解釈することを主張するコード機能。たとえば、 '<'があり、それをユーザーに '<'として表示したい場合、HTML内に文字列を残酷に貼り付けると、クライアント側のWebブラウザは '< '単純な' <'を表すのではなく、HTMLタグで始まると考えます。

一般に、文字列を文字列として保持し、エンコーディングまたはエスケープを適切に行う特殊な関数に委任する必要があります。たとえば、SQLの場合、 準備済みステートメント を使用します。 PHPコンテキストからのHTMLでは、 htmlspecialchars() を使用します。

ここで注意すべき点は、実行する必要がある変換、エンコード、またはエスケープの種類は、文字列で何をしようとしているのかによって異なるということです。文字列をHTMLに配置する必要がある場合は、HTMLエンティティ(&lt;(「<」など) すでにエスケープされた文字列をデータベースに保存している場合、文字列onlyを使用することで、一部のHTML。

したがって、使用時にのみエンコード/エスケープを適用するように努力する必要があります。より柔軟で、セマンティクスが単純になります。データベース内で、文字列を文字列として保存します。

11
Tom Leek

編集: Lucは、私が高性能ソリューションに過度に傾倒しているという概念で指摘しました。自分の状況でパフォーマンスが問題にならない場合は、元のデータのみを保存して出力に変換することは完全に許容できます(実際には望ましいことです)。これにより、データを柔軟に使用できますが、バージョンを維持せずに必要になります。

以下の元の回答----------------------------------------------- -------

ある程度、状況によって異なります。第1に、生データを保存し、それを読み戻すときにエスケープすることはほとんどありません。

2つの一般的なソリューションは次のとおりです。

1)データを保存する前にエスケープします。

2)データの2つのコピーを保存します。1つはエスケープ、もう1つは生です。

事実上、どのシステムでも、読み取りと書き込みの比率は、読み取りに大きく傾いています。 10:1の場合もありますが、10,000:1の場合もあります。これが、エスケープされた形式でデータを格納し、データを読み取るときに毎回ではなく、書き込み時にのみ解析したい理由です。

両方の形式を保存する利点は、元の作成者が意図したとおりにコンテンツを変更できること、必要に応じてコンテンツを再処理できること、元のデータを確認できることです...これにより、多少の追加費用である程度の柔軟性が得られます。複雑。

これは明らかに少し単純化しています。たとえば、キャッシュが読み取り/書き込み比率に及ぼす影響を考慮していないためですが、一般的な概念が伝わるといいのですが。

0
Xander