3

XSSを軽減しようとしています。これからどうすればシールドできますか:

j&#X41vascript:alert('test2')

hrefリンクの

私は次のことを試しましたが、javascript:コード実行をトリガーできる適切な href ではなく、上記の文字列のリテラルの未解決の値を href の相対パスとして割り当てるだけです。攻撃者がこれをどのように悪用できるのか疑問に思っています。

私は次のことを試しました:

a = document.createElement('a');

そして、これの両方:

a.href = 'j&#X41vascript:alert('test2')';

この:

a.setAttribute('href', "j&#X41vascript:alert('test2')");

しかし、両方とも"j&#X41vascript:alert('test2')"クエリa.hrefを実行すると、望ましいものではなく(または視点によっては望ましくない)返されますjavascript:alert('test2');

すべてのエンティティを解決することができればjavascript:、結果の文字列に出現するすべての を解析して安全にすることができます。

私が考えていたもう1つのことは、誰かがそうしたらどうなるかということでしたjvascript:steal_cookie();。つまり、理論的には、無限レベルの再帰が可能であり、最終的にはすべて解決されるということですよね?


編集: このコードはどのように見えますか?

function resolve_entities(str) {
  var s = document.createElement('span')
    , nestTally = str.match(/&/) ? 0 : 1
    , limit = 5
    , limitReached = false;

  s.innerHTML = str;
  while (s.textContent.match(/&/)) {
    s.innerHTML = s.textContent;
    if(nestTally++ >= limit) {
      limitReached = true;
      break;
    }
  }

  return s.textContent;
}
4

3 に答える 3

4

Aまたはのような XML/HTML 文字エンティティは、それらを含む文字列が XML または HTML として解析されるときに&デコードされます。通常、これは HTML ページの一部としてサーバーからブラウザーに送信されるときに発生しますが、文字列が XML または HTML として解析される可能性がある他の状況 (JavaScript での割り当てなど) もあります。element.innerHTML

JavaScript での要素属性の読み取りまたは書き込みは、XML/HTML 解析をトリガーしないため、文字エンティティを展開しませんあなたが書くなら

a.href = "jAvascript:alert('test')";

その要素のhref属性は、アンパサンドおよびすべてになります。ajAvascript:alert('test')

注意すべき重要な点は、文字列が XML または HTML として解析されるたびに、文字エンティティが1 回だけデコードされるということです。したがって、 に&x41;なりますがa、 にAなりAます。読み取りと割り当てを繰り返し行うなどの愚かなことをしない限り、「すべてが最終的に解決する」ことはありません。.textContent.innerHTML

解析が完了すると、出力内の文字シーケンスが XML/HTML 文字エンティティのように見えるかどうかはまったく関係ありません。つまり、出力を取得して XML/HTML パーサーに再度送り込まない限りです。(これを行うことはめったに有用ではなく、通常は に割り当てる必要があるときに に割り当てるなどのバグが原因でのみ発生します。).innerHTML.textContent


とにかく、コメントを見て、あなたが書いているクライアント側の JavaScript コードは、あなたが制御していないサーバーから信頼できないデータを取得していて、単純にデータを割り当てるだけで.innerHTMLXSS 攻撃が可能になるのではないかと心配しています。その場合、次の 2 つのケースがあります。

  1. 受け取るデータはプレーンテキストです。その場合、それをに割り当てて、それで.textContent完了する必要があります。

  2. 受け取るデータは、実際には HTML であることを意図しています。その場合、それを消毒するという困難で面倒な作業を行う必要があります。 Caja プロジェクトのこの JavaScript HTML サニタイザーが役立つかもしれません。

于 2012-09-08T15:12:19.303 に答える
2

コンテンツが整形式である限り、XMLを使用して安全に解析できます。少なくとも出発点(フィドル)として、このようなもの:

function getXmlDoc(s) {
    var parser;
    if(DOMParser){
        parser = new DOMParser();
        xmlDoc = parser.parseFromString(s, "text/xml");
    } else {
        // IE
        xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = false;
        xmlDoc.loadXML(s); 
    }
    return xmlDoc;
}

var xml = getXmlDoc("<root>j&#x0061;vascript:alert('test2')</root>");
alert(xml.documentElement.firstChild.nodeValue);

</ p>

ただし、おそらく安全でない文字をエスケープするだけです。

function safeEscape(s) {
    return s.replace(/[\&\<\>]/g, function($0) {
        switch($0) {
            case '&': return '&amp;';
            case '<': return '&lt;';
            case '>': return '&gt;';
        }
    });
}

再帰的にエスケープされた文字で問題が発生することは許可されていないため、発生しないでください。

于 2012-09-08T13:58:50.107 に答える
2

XSS を軽減する最善の方法は、画面にレンダリングされるすべての信頼できない出力を、出力が含まれるコンテキスト (HTML、HTML 属性、CSS、JS など) に適したエンコーディング メソッド メソッドを使用してエンコードすることです。

この問題をなんとか解決できたとしても、考えもしなかったエンコーディングを使用した他の攻撃ベクトルが存在する可能性があります。ブラックリスト フィルターがサイトを保護する最も効果的な方法であることはめったにありません (あったとしても)。

使用しているサーバー側の言語はわかりませんが、そのためのエンコーディング ライブラリが存在する可能性があります。ESAPIはいくつかの言語で利用でき、この目的のために構築されました (さらに多くの他の言語も)。

更新: これには JavaScript を使用する必要があるため、ESAPI Encoding Project (Reform) を確認することをお勧めします。それはあなたが必要とすることをするように見えるJSバージョンを持っています. 私はテストしていませんが、ESAPI のように動作する場合は、問題が解決する可能性があります。

コンテキストごとの適切なエンコーディングの詳細については、OWASP XSS 防止チート シートをご覧ください。

于 2012-09-08T14:03:40.487 に答える