54

既知の XSS またはその他の攻撃で、

$content = "some HTML code";
$content = strip_tags($content);

echo $content;

?

マニュアルには次の警告があります。

この関数は、いたずら好きなユーザーが他のユーザーに表示されるテキストを投稿するときに悪用する可能性のある style および onmouseover 属性を含む、allowable_tags を使用して許可するタグの属性を変更しません。

allowable_tagsただし、それはパラメーターのみの使用に関連しています。

許可されたタグが設定されていない場合、strip_tags()攻撃に対して脆弱ですか?

Chris Shiflettは安全だと言っているようです:

成熟したソリューションを使用する

可能であれば、独自のソリューションを作成するのではなく、成熟した既存のソリューションを使用してください。strip_tags() や htmlentities() などの関数は適切な選択です。

これは正しいです?可能であれば、ソースを引用してください。

HTML purifier、htmlspecialchars() などについては知っています。HTML をサニタイズするための最良の方法を探しているわけではありません。この特定の問題について知りたいだけです。これはここで出てきた理論的な問題です。

参考:strip_tags()PHPソースコードでの実装

4

5 に答える 5

53

その名前が示すように、strip_tagsすべての HTML タグを削除する必要があります。それを証明できる唯一の方法は、ソース コードを分析することです。次の分析はstrip_tags('...')、ホワイトリストに登録されたタグの 2 番目の引数なしで呼び出しに適用されます。

まず、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 関数は、 ext/standard/string.c の 4036 行strip_tagsで参照されています。その関数は、内部関数 php_strip_tags_exを呼び出します。

出力用と「HTML タグ内」用の 2 つのバッファが存在します。という名前のカウンターdepthは、開き山かっこ ( <) の数を保持します。
変数in_qには、引用符 ('または") がある場合はそれが含まれ、それ以外の場合は含まれ0ます。最後の文字は変数に格納されますlc

関数は 5 つの状態を保持します。3 つの状態は、関数の上の説明で言及されています。この情報と関数本体に基づいて、次の状態を導き出すことができます。

  • 状態 0 は出力状態です (どのタグにもありません)。
  • 状態 1 は、通常の html タグ内にあることを意味します (タグ バッファには が含まれます<) 。
  • 状態 2 は、php タグ内にいることを意味します
  • 状態 3: 出力状態から来て、<および!文字に遭遇しました (タグ バッファには が含まれています<!)
  • 状態 4: HTML コメント内

タグを挿入できないことに注意する必要があります。つまり、<空白以外の文字が続きます。行 4326<は、以下に説明する文字のケースをチェックします。

  • 引用符で囲まれている場合 (例: <a href="inside quotes">)、その<文字は無視されます (出力から削除されます)。
  • 次の文字が空白文字の場合<は、出力バッファーに追加されます
  • HTML タグの外側の場合、状態は1(「HTML タグの内側」) になり、最後の文字lcが に設定されます。<
  • それ以外の場合、HTML タグ内の場合、指定されたカウンターdepthがインクリメントされ、文字は無視されます。

>タグが開いている間に が満たされると ( ) state == 1、(「引用符内にない」) にin_qなり、(「タグ内にない」) になります。タグ バッファは破棄されます。0state0

属性チェック ('や などの文字の場合") は、破棄されるタグ バッファーで行われます。したがって、結論は次のとおりです。

タグ ホワイトリストのない strip_tags は、タグの外側に含めても安全です。タグは許可されません。

「外側のタグ」とは、のようにタグ内にないことを意味します<a href="in tag">outside tag</a>。のように、テキストには<andが含まれる場合があり>ます>< a>>。ただし、結果は有効な HTML では<なく>&特に&. それはで行うことができますhtmlspecialchars()

strip_tagsホワイトリスト引数がない場合の説明は次のようになります。

返された文字列に HTML タグが存在しないことを確認します。

于 2011-04-26T16:35:12.857 に答える
11

特にこのためのPHPソースコードを調べていないため、将来のエクスプロイトを予測することはできません。ただし、ブラウザが一見無効なタグ(など)を受け入れるため、過去にエクスプロイトが発生しました<s\0cript>。したがって、将来、誰かが奇妙なブラウザの動作を悪用できる可能性があります。

それはさておき、HTMLの完全なブロックとして出力をブラウザに直接送信することは決して安全ではありません。

echo '<div>'.strip_tags($foo).'</div>'

ただし、これは安全ではありません。

echo '<input value="'.strip_tags($foo).'" />';

"スクリプトハンドラを介して簡単に見積もりを終了し、挿入できるためです。

<常に迷子をに変換する方がはるかに安全だと思います&lt;(引用符も同じです)。

于 2011-04-26T16:54:11.927 に答える
2

ストリップ タグは完全に安全です。テキストを html 本文に出力するだけの場合です。

mysql または url 属性に入れることは必ずしも安全ではありません。

于 2011-04-26T10:08:48.220 に答える