ユーザーが生成/送信した情報を表示する際に、他の特殊文字をエスケープしてアンパサンドをそのままにしておくと、セキュリティ上のリスクはありますか? サニタイザーに不必要な複雑さを加えることなく、ユーザーが HTML エンティティ、16 進数、および 10 進数の特殊文字を自由に入力できるようにしたいと考えています。
2 に答える
それはすべて、データが配置されるコンテキストに依存します。
&
HTML では、プレーンを文字参照で表す主な理由は、あいまいさを避けるためです&
。これは、文字参照の開始でもあります。このようなあいまいさの一般的な例は、&
次のような HTML 属性の URL パラメータの一部としてのプレーンです。
<a href="/?lang=en§=foobar">
ここで&
は、 が対応する文字参照で適切にエンコードされていないため、パーサーはこれを文字参照の開始として扱います。また、sectはセクション文字を表すHTML の既知のエンティティであるため、この属性値は実際には として解釈されます。 §
/?lang=en§=foobar
したがって、プレーン&
をそのままにしておくと、HTML の他の特殊文字のように、データが配置されるコンテキストを変更できるため、実際の脅威が発生することはありません。
- タグ区切り文字
<
であり>
、タグ宣言を開始または終了できます。 - 属性値の区切り記号
"
であり'
、属性値の宣言を開始または終了できます。
安全のために、 double_encodeパラメータを に設定して使用htmlspecialchars
し、既存の文字参照の二重エンコーディングを回避する必要があります。false
var_dump(htmlspecialchars('<"&\'>', ENT_QUOTES, 'UTF-8', false) === '<"&'>'); // bool(true)
tldr; アンパサンド (またはその他の「特殊文字」) を残しても、正しくコーディングされていればセキュリティ上の問題にはなりません。つまり、入力ではなく、出力/使用が重要です。
それはすべて、最終的にデータがどのように使用されるかにかかっています。たとえば、任意の入力に対してa を行うこと<input value="<? echo $input ?>" />
は正しくコーディングされていません。
多くの場合、は他の文字 ( 、、または など)&
よりもはるかに「問題」が少ないですが、状況によってはアーティファクト (エラーや未定義の動作を含む) を引き起こす可能性があります。 URL'
"
<
>
- ..しかし、出力時にURL が適切にエンコードされていない場合は、正しくコーディングされていません 1
- .. もちろん、 a
&
がそのまま XML/HTML ストリームに書き込まれている場合、正しくコーディングされていません 2 - ..そして、プログラムが
&
[ユーザー入力から]「シェル文字列実行」に生で渡されている場合、それは[非常に可能性が高い]正しくコーディングされていません 3 - ..すべては使用に帰着します。
ビジネスルールに準拠させることを除いて、入力を変更しない傾向があります-これには上記のケースは含まれません! (しかし、アンパサンドをまったく受け入れないことは、完全に有効なビジネス ルールである可能性があります。)
適切なタイミングでの適切なエスケープ (または、[手動] エスケープを必要としないアプローチ) により、残りの処理が行われ、使用法を適切にコーディングすることで、些細な攻撃や偶発的な失敗が軽減されます。
実際、この種の「入力サニタイズ」は、他の場所で使用されているアプローチ/コードへの信頼の欠如を示しており、「サニタイズ」を元に戻す必要があるというより多くの問題につながる可能性があると主張します。マジックは誰かを引用しますか?
1これは&
、ユーザー入力の が実際に何らかの形で注入を引き起こす可能性がある場合です。想像してみてください:format("http://site/view={0}", user_input)
がuser_input
含まれています1&buy=1
。結果は になります"http://site/view=1&buy=1"
。正しい方法は、値をURI エンコード (別名、パーセント エンコード)"http://site/view=1%26buy%3D1"
することです。(正しくコーディングされた場合、クエリ パラメータは 1 つだけであることに注意してください。意図が「生の」入力を通過できるようにすることである場合は、許容されるルールを慎重に定義/分析し、次の段落を参照してください。)
2 HTML ストリームでは「素」&
が有効である可能性がありますが、ユーザー入力は「有効な HTML である」と信頼されるべきではありません。つまり、XML または HTML を対象としているかどうかに関係なく、正しい出力/レンダリング エスケープ メカニズムを使用する必要があります。(エスケープメカニズムは「そのままの」 をエンコードしないことを選択するかもしれません&
が、それは二次的な懸念事項です。怠惰なプログラマーは、一貫性のある信頼性の高い安全な出力を得るために、適用可能なすべての出力に対して同じエスケープ手法を使用し続けます。)
3解析する必要がある単一の引数文字列を取る shell-execute を使用する代わりに、引数のリストを受け取る exec-form を使用します。後者は [一般的に] シェルと関連するシェル ハックの生成を防ぎます。そしてもちろん、ユーザーが手動で実行可能ファイルを指定することは決してありません..