48


34

セキュリティを処理し、ユーザーが入力したURLでXSSを回避するための最良の方法

セキュリティの高いアプリケーションがあり、他のユーザーに表示されるURLをユーザーが入力できるようにしたいと考えています。

これはXSSハッキングの危険性が高いことをもたらします - ユーザーが潜在的に別のユーザーが実行してしまうJavaScriptを入力する可能性があります。 機密データを保持しているので、これが決して起こらないことが不可欠です。

これに対処するためのベストプラクティスは何ですか? セキュリティホワイトリストやエスケープパターンだけで十分ですか。

リダイレクトの処理に関するアドバイス(リンクをたどる前に警告ページに「このリンクはサイト外にあります」というメッセージが表示されるなど)

ユーザーが入力したリンクをまったくサポートしていないという議論はありますか?

'' '' '

明確化:

基本的に私達のユーザーは入力したいと思います:

_ stackoverflow.com _

そしてそれを他のユーザに出力させます:

stackoverflow.com

私が本当に心配しているのは、彼らがXSSハックでこれを使っていることです。 I.e. 彼らは入力します:

_ alert( 'hacked!'); _

だから他のユーザーはこのリンクを得る:

stackoverflow.com

私の例はリスクを説明することだけです - 私はJavascriptとURLが異なることをよく知っていますが、後者を入力させることによって前者を実行することができるかもしれません。

あなたはこのトリックで何個のサイトを破ることができるかに驚かれるでしょう - HTMLはさらにもっと悪いです。 彼らがリンクを扱うことを知っているならば、彼らはまた をサニタイズすること、そして賢いCSS参照を知っていますか?

私は高度なセキュリティ環境で働いています - 単一のXSSハックは私たちにとって非常に大きな損失につながる可能性があります。 私が考えることができるすべてを除外することができるRegexを作り出すことができたこと(またはこれまでのところ素晴らしい提案の1つを使用すること)ができてうれしいですが、それで十分でしょうか?

9 Answer


52


URLにコードを含めることはできないと思われる場合は、もう一度考えてください。

それを読んで、泣いてください。

これがスタックオーバーフローでどのように行われるかです。

///
/// returns "safe" URL, stripping anything outside normal charsets for URL
///
パブリック静的文字列SanitizeUrl(文字列url){return Regex.Replace(url、@ "[^  -  A-Za-z0-9


13


リンクを「安全」にするプロセスは、3つまたは4つのステップを経なければなりません。

  • あなたが与えられた文字列をエスケープ解除/再エンコードします(RSnakeは http://ha.ckers.org/xss.htmlhttp://ha.ckers.org/xss.htmlでいくつかのトリックを文書化しました。エスケープとUTFエンコーディングを使用してください。

  • リンクをきれいにする:正規表現から始めるのがよいでしょう - 文字列を切り捨てるか、 "(または出力の属性を閉じるために使用するものはすべて)が含まれている場合はそれを破棄してください。他の情報については、このプロセスの最後にプロトコルを強制することもできます - 最初のコロンの前の部分が 'http’でも 'https’でもない場合は、最初に 'http://'を追加します。 これにより、ユーザーがブラウザに入力するときに、不完全な入力から使用可能なリンクを作成でき、誰かがこっそり侵入しようとしたいたずらを解決するための最後の一歩を踏み出すことができます。

  • 結果が正しいURLであることを確認します(プロトコル://host.domain [:port] [/ path] [/ [file]] [?queryField = queryValue] [#anchor])。

  • サイトのブラックリストと比較して結果を確認するか、何らかの種類のマルウェアチェッカーを使用して結果を取得してください。

セキュリティが最優先事項であるならば、たとえそれが安全なリンクを捨てることになったとしても、私はユーザーがこの過程で少しのパラノイアを許すことを望むでしょう。


8


OWASP-ESAPI APIなどのライブラリを使用します。

以下を読んで:

例えば:

$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$esapi = new ESAPI( "/etc/php5/esapi/ESAPI.xml" ); // Modified copy of ESAPI.xml
$sanitizer = ESAPI::getSanitizer();
$sanitized_url = $sanitizer->getSanitizedURL( "user-homepage", $url );

もう1つの例は、組み込み関数を使用することです。 PHPのhttp://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.c?view=markup[filter_var]関数はその一例です。

$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$sanitized_url = filter_var($url, FILTER_SANITIZE_URL);

filter_var allows javascript呼び出しを使用して、` http`でも `https`でもないスキームを除外します。 https://code.google.com/p/owasp-esapi-php/source/browse/trunk / src / Sanitizer.php[OWASP ESAPI Sanitizer]を使用するのがおそらく最良の選択肢です。

さらに別の例はhttp://codex.wordpress.org/Function_Reference/esc_url[WordPress]からのコードです:

さらに、URLがリンクしている場所を知る方法がないため(つまり、有効なURLでもURLの内容がいたずら好きになる可能性があるため)、https://developers.google.com/safe-browsingにアクセスします。 / [安全な閲覧]あなたが呼ぶことができるAPI:

衛生管理のために独自の正規表現を使用することは、いくつかの理由で問題があります。

  • あなたがJon Skeetでない限り、コードにはエラーがあります。

  • 既存のAPIには、何時間ものレビューとテストがあります。

  • 既存のURL検証APIは国際化を考慮しています。

  • 既存のAPIは、新しい標準に従って最新の状態に保たれます。

考慮すべきその他の問題:

  • どのスキームを許可しますか(「file:///」と「telnet://」 許容できる)?

  • URLのコンテンツにどのような制限を設定しますか( マルウェアのURLは受け入れられますか?)


3


あなたはあなたのアプリケーションの言語を指定しません、私はそれからASP.NETを仮定します、そしてこれのためにあなたは Microsoft Anti-Crossを使うことができますサイトスクリプティングライブラリ

それは非常に使いやすいです、あなたが必要とするすべてはインクルードであり、それはそれです:)

話題になっている間は、なぜ セキュアWebアプリケーションの設計ガイドラインを読んではいけません。

他の言語なら…… ASP.NET用のライブラリがある場合は、他の種類の言語(PHP、Python、RORなど)にも使用可能でなければなりません。


3


リンクをHTMLEncodeして出力するだけです。 `javascript:`リンクを許可しないようにしてください。 (http、https、mailtoなど、承認されているプロトコルのホワイトリストを用意するのが最善です。)


1


それらをリンクとして表示しないのはどうですか。 テキストを使うだけです。

ご自身の責任で続行するように警告を組み合わせることで十分な場合があります。

追加 - ユーザー入力のサニタイズについての議論は ホストされたCMSのHTMLマークアップをサニタイズする必要がありますか?


0


JavaScriptで書かれた私のプロジェクトでは、この正規表現をホワイトリストとして使用しています。

url.match(/ ^((https?| ftp):\ / \ / | \。{0,2} \ /)/)

唯一の制限は、あなたが同じディレクトリのファイルのために前に./を置く必要があるということですが、私はそれで生きることができると思います。


-1


URL全体を変換してサーバーに送信するには、16進コードを使用できます。 そのようにクライアントは一見しただけでは内容を理解できません。 コンテンツを読み終えたら、コンテンツのURLをデコードできます。 そしてそれをブラウザに送ります。


-7


URLを許可することとJavaScriptを許可することは2つの異なることです。