既知のXSSまたはそれを通過させる他の攻撃はありますか
_$content = "some HTML code";
$content = strip_tags($content);
echo $content;
_
?
manual には警告があります:
この関数は、他のユーザーに表示されるテキストを投稿するときに悪意のあるユーザーが悪用する可能性のあるスタイルやonmouseover属性など、acceptable_tagsを使用して許可するタグの属性を変更しません。
ただし、これは_allowable_tags
_パラメータの使用にのみ関連しています。
許可されたタグが設定されていない場合、strip_tags()
は攻撃に対して脆弱ですか?
Chris Shiflett は安全だと言っているようです:
成熟したソリューションを使用する
可能であれば、独自のソリューションを作成する代わりに、成熟した既存のソリューションを使用してください。 strip_tags()やhtmlentities()などの関数が適しています。
これは正しいです?可能であれば、出典を引用してください。
HTMLピュリファイア、htmlspecialchars()などについて知っています。-HTMLをサニタイズするための最良の方法を探していますではありません。この特定の問題について知りたいだけです。これは出てきた理論的な質問です here 。
リファレンス: strip_tags()
PHPソースコード の実装
その名前が示すように、_strip_tags
_はすべてのHTMLタグを削除する必要があります。それを証明できる唯一の方法は、ソースコードを分析することです。次の分析は、ホワイトリストタグの2番目の引数なしのstrip_tags('...')
呼び出しに適用されます。
まず最初に、HTMLタグに関するいくつかの理論:タグは_<
_で始まり、その後に非空白文字が続きます。この文字列が_?
_で始まる場合、それは 解析されるべきではありません です。この文字列が_!--
_で始まる場合、コメントと見なされ、次のテキストも解析されません。コメントは_-->
_で終了します。このようなコメント内では、_<
_や_>
_などの文字を使用できます。属性はタグで使用でき、それらの値はオプションで引用文字(_'
_または_"
_)で囲むことができます。そのような引用が存在する場合は、それを閉じる必要があります。それ以外の場合、_>
_が検出された場合、タグは閉じられません。
コード_<a href="example>xxx</a><a href="second">text</a>
_は、Firefoxでは次のように解釈されます。
_<a href="http://example.com%3Exxx%3C/a%3E%3Ca%20href=" second"="">text</a>
_
PHP関数 _strip_tags
_ は ext/standard/string.cの行4036 で参照されています。この関数は- 内部関数php_strip_tags_ex 。
2つのバッファが存在し、1つは出力用、もう1つは「HTMLタグ内」用です。 depth
という名前のカウンターは、山かっこ(_<
_)の数を保持します。
変数_in_q
_には、引用符文字(_'
_または_"
_)が含まれている場合は含まれ、そうでない場合は_0
_が含まれます。最後の文字は変数lc
に格納されます。
関数には5つの状態があり、3つは関数の上の説明で説明されています。この情報と関数本体に基づいて、次の状態を導出できます。
<
_が含まれています)。<
_および_!
_文字を検出しました(タグバッファーに_<!
_が含まれています)タグを挿入できないように注意する必要があります。つまり、_<
_の後に空白以外の文字が続きます。 4326行目 は、次に説明する_<
_文字を使用してケースをチェックします。
<a href="inside quotes">
_)、_<
_文字は無視されます(出力から削除されます)。<
_が出力バッファーに追加されます。1
_( "HTMLタグ内")になり、最後の文字lc
は_<
_に設定されますdepth
という名前のカウンターがインクリメントされ、文字は無視されます。タグが開いているときに_>
_が満たされた場合(_state == 1
_)、_in_q
_は_0
_(「引用符で囲まれていない」)となり、state
は_0
_(「タグにない」)。 タグバッファは破棄されます。
属性チェック(_'
_および_"
_などの文字の場合)は、破棄されたタグバッファーで行われます。したがって、結論は次のとおりです。
タグのホワイトリストのないstrip_tagsは、タグの外側に含めても安全です。タグは許可されません。
「外部タグ」とは、_<a href="in tag">outside tag</a>
_のようにタグ内にないことを意味します。ただし、_<
_のように、テキストには_>
_および_>< a>>
_を含めることができます。結果は有効なHTMLではありませんが、_<
_、_>
_、および_&
_、特に_&
_は、エスケープする必要があります。 htmlspecialchars()
でそれを行うことができます。
ホワイトリスト引数なしの_strip_tags
_の説明は次のようになります。
返された文字列にHTMLタグが存在しないことを確認します。
特にPHPソースコードを確認していないため、今後のエクスプロイトを予測することはできません。ただし、ブラウザが一見無効なタグ(_<s\0cript>
_)。したがって、将来、誰かが奇妙なブラウザの動作を利用できるようになる可能性があります。
それはさておき、HTMLの完全なブロックとしてブラウザに直接出力を送信することは決して安全ではありません:
_echo '<div>'.strip_tags($foo).'</div>'
_
ただし、これは安全ではありません。
_echo '<input value="'.strip_tags($foo).'" />';
_
_"
_を介して引用を簡単に終了し、スクリプトハンドラーを挿入できるためです。
Stray _<
_を_<
_に常に変換する方がずっと安全だと思います(引用符でも同じです)。
このオンラインツール によると、この文字列は「完全に」エスケープされますが、結果は別の悪意のあるものになります!
<<a>script>alert('ciao');<</a>/script>
文字列では、「実際の」タグは<a>
と</a>
です。これは、<
とscript>
だけがタグではないためです。
私が間違っているか、古いバージョンのPHPが原因であると思いますが、環境で確認することをお勧めします。
タグを取り除くことは完全に安全です-あなたがしているすべてがテキストをhtml本文に出力することである場合。
Mysqlまたはurl属性に入れるのは必ずしも安全ではありません。