私はいつも、フォーラムやブログのようなWebソフトウェアを書くことに興味がありました。しかし、最近、私はPHPのために "PHP BBCode parser -PEAR"をテストし、いくつかのテストをすると、非効率的な混乱を招くか、XSSの穴があちこちにあるコードが貧弱になることに気づきました。正規表現と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の実装に特有です。
- この例では、uri/url検証式を使用して一致させるほうがよいでしょうか?または、
(.*?)
とコールバックを使用し、入力が有効なリンクであるかどうかを確認する方が良いでしょうか?上で明らかなように、javascript:alert('XSS!')
は上記のURLタグで動作しますが、uri-matchingが行われた場合は失敗します。 - コールバック内で
urlencode()
のような機能はどうでしょうか(これはURI標準が適用される限り)どんな抑止力や問題でもありますか? - フルスタックパーサーを書く方が安全でしょうか?あるいは、ページあたりいくつかの異なるエントリを処理するために、あまりにも重いものを開発し使用するために必要な時間と処理能力はありますか?
私の例は多くのものの一つであり、いくつかよりも具体的であることが分かります。しかし、あなた自身を提供することから面倒ではありません。 私は、原則とベストプラクティス、およびテキスト解析の状況でのXSS保護の一般的な推奨事項を探しています。アウト
ええと、あなたの言ったところで私はあなたに同意しますが、私は適切なパーサーを作ることに多くのスキルを持っていません。 XML風の解析のための適切なチュートリアルを知っていますか?私はそれほど複雑ではないがまだ必要なスキルレベルにある良いものを見つけるのは難しいと感じました。 –
あなたのニーズを満たすサードパーティのパーサライブラリが見つからない場合は、手作業で行うことができます:まず、 '\ [[^ \]] + \]'のような文字列をpreg_split-with-PREG_SPLIT_DELIM_CAPTUREタグを選択し、開いているタグのスタックを保持してリストを歩きます。 – bobince
(リスト内の偶数番号のインデックスは、テキスト、奇数番号のタグです。通常、テキストはHTMLエスケープされ、スマイリーが自動配置されることがあります。 – bobince