1

私は常に、フォーラムやブログのような Web ソフトウェアを作成することに興味を持っていました。これは、限定的なマークアップを使用して HTML に書き直すものです。しかし最近、PHP について、「PHP BBCode parser -PEAR」をググってみて、いくつか試してみると、非効率的な混乱が生じるか、あちこちに XSS ホールのある貧弱なコードが得られることにますます気づきました。

前述の貧弱な BBCode パーサーの例を挙げると、どのように XSS を回避しますか? リンクを処理するための典型的な正規表現を取り上げます。リンクの脆弱性と回避方法について言及できます。

// Assume input has already been encoded by htmlspecialchars with ENT_QUOTES
$text = preg_replace('#\[url\](.*?)\[/url\]#i','<a href="\1">\1</a>', $text);
$text = preg_replace('#\[url=(.*?)\](.*?)\[/url\]#i','<a href="\1">\2</a>', $text);

画像タグの処理は、これほど安全ではありません。

そのため、主に PHP の実装に固有の質問がいくつかあります。

  1. この例では、uri/url 検証式を使用してのみ一致させることをお勧めしますか? または、コールバックを使用(.*?)してから、入力が有効なリンクかどうかを確認する方がよいでしょうか? 上記で明らかなようにjavascript:alert('XSS!')、上記の URL タグでは機能しますが、URI マッチングが行われると失敗します。
  2. コールバック内のような関数はどうurlencode()ですか? (URI 標準に関する限り) 抑止力や問題になりますか?
  3. フルスタック パーサーを作成する方が安全でしょうか? それとも、そのようなものを開発して使用するために必要な時間と処理能力は、ページごとに複数の異なるエントリを処理するものには重すぎますか?

私の例は多くの例の 1 つであり、いくつかの例よりも具体的であることはわかっています。ただし、独自のものを提供することをためらわないでください。 そこで、テキスト解析状況における XSS 保護の原則とベスト プラクティス、および一般的な推奨事項を探しています。

4

1 に答える 1

4

いくつかテストすると、非効率な混乱が発生するか、XSS ホールのある貧弱なコードが得られます

ええ。XSS 脆弱性のない bbcode 実装にはまだ会ったことがありません。

'<a href="\1">\1</a>'

ダメ: HTML エスケープ '<', '&' に失敗する および '"' 文字。

この例では、uri/url 検証式を使用してのみ一致させることをお勧めしますか? または、(.*?) とコールバックを使用して、入力が有効なリンクかどうかを確認する方がよいでしょうか?

コールバックを受け取ります。とにかく、HTML エスケープを行うにはコールバックが必要です。単純な文字列の置換だけでは安全ではありません。あなたがそれをしている間、消毒剤を落としてください。

コールバック内の urlencode() のような関数はどうですか

ほぼ; 実際には htmlspecialchars() が必要です。urlencode() はクエリ パラメータのエンコードに関するものであり、ここでは必要ありません。

フルスタック パーサーを作成する方が安全でしょうか?

はい。

bbcode は再帰的なタグベースの言語 (正規表現も解析できない XML など) であるため、正規表現の解析には適していません。多くの bbcode ホールは、ネストやミスネストの問題によって引き起こされます。例えば:

[url]http://www.example.com/[i][/url]foo[/i]

次のようなものとして出てくる可能性があります

<a href="http://www.example.com/&lt;i>">foo</i>

さまざまな bbcode 実装で壊れたコード (XSS ホールを含むまで) を生成する他の多くのトラップがあります。

原則とベストプラクティスを探しています

正規表現できる bbcode のような言語が必要な場合は、次のことを行う必要があります。

  • 他のタグ内に配置できるタグの数を減らします。任意のネストをサポートすることは実際には不可能です
  • 「<」には特殊文字を使用してください および「>」HTML タグの区切り記号。テキスト内に表示される実際の山かっこと区別します。私は ASCII 制御コードを使用します (以前はユーザー入力段階で制御文字を除外していました)。
  • これらの制御文字で処理されている文字列をこれら 2 つの制御文字の間のコンテンツに分割して、bbcode スパンがタグ内またはタグ境界を越えて到達しないようにします。
  • タグの境界を越えて到達する bbcode スパンを外側から内側に作用させることはできないため、最初に大きなブロック要素を実行し、リンクに向かって内側に作用し、最後に太字と斜体になります。
  • 健全性のために、一度にブロックを処理します。例えば。二重改行で新しい <p> を開始する場合、bbcode タグは 2 つの別個のブロック間にまたがることはできません。

正しくするのはまだ大変です。適切なパーサーは、ウォータータイトである可能性がはるかに高くなります。

于 2009-04-09T17:27:19.593 に答える