web-dev-qa-db-ja.com

JSON.parseとhref属性から抜け出すXSS

悪意のあるファイル名のjpgファイルをアップロードするときに、保存されたXSS攻撃を実行しようとするかなり複雑なケースがあります。

空白はフィルタリングされていますが、<>とともに単一引用符と二重引用符がフィルタリングされていないようです。さらに、スラッシュ/およびバックスラッシュ\は禁止されているようです。

ユーザー制御の入力はファイル名です。このファイル名は、最初に次の方法でJSONデータを作成するjsスクリプトに渡されます(ユーザー制御のファイル名はINJECT_HEREとして表されます)。

<script>
var foo = JSON.parse('{"x":1,"id":"2","myarr":[{"x1":"1"}],"x2":[{"id1":3,"id2":"15","name":"INJECT_HERE","path":"\/uploads\/pics\/1\/INJECT_HERE","b":"1"}]}')
</script>

次に、上記の変数を使用して、ユーザー指定の入力をHTML要素に渡します。ファイル名(foo.myarr.x2.nameを介して)がhref属性(vue-jsおよびv-bindを使用)に渡され、結果のhtmlは次のようになります。

<div href="https://localhost/INJECT_HERE" class="foobar"></div>

保存されたXSSを実行するために、同時に両方のコンテキストから抜け出すにはどうすればよいですか?それは実現可能ですか、それともできないことを試みますか?

5
XII

できません。 VueはDOMを使用してhref属性を設定するため、HTMLパーサーをだますような方法でサーバーからハードコーディングされていません。DOMで属性を設定することは単に不可能です。つまり、生のHTMLソースがあるかのように、属性を「抜け出す」か、新しい属性を開始します。開発ツールの生の値によって攻撃が機能しているように見えても、無効な文字はすべて論理的にエスケープされます。

サーバーでテンプレートのいずれかを行った場合(おそらく事前レンダリングの試みで)、それは問題ですが、現状では安全です。

_data:_および_javascript:_のURLも問題になる可能性があることに注意してください。ただし、専門知識のレベルが明らかな場合は、その設定から既に保護されている可能性があります。

編集:コメントに応答

dOMを使用してコンテンツを挿入する単純なページを考えてみます。

_<html> 
   <a id=a href="#">xss</a>
   <script>a.href='"><script>alert(123)<\/script>';</script>
</html>
_

開発者ツールのインスペクションビューを見ると、次のような恐ろしいことがわかります。

<a id="a" href=""><script>alert(123)</script>">xss</a>

_<script>_タグ内に_<a>_タグがあるように見えますが、実際にそれを空白のページにコピーして表示すると、警告が表示されます。ただし、開発者ツールが視覚的なトリックを実行しているため、実際には問題ありません。シリアル化されたときの要素の実際の内容は、次のようになります。

<a id="a" href="&quot;&gt;&lt;script&gt;alert(123)&lt;/script&gt;">xss</a>

それが、DOMが任意のコンテンツを自動エスケープすることによって私が意味したことです。 DOMを使用して属性を設定している限り、属性で属性を「バストアウト」する方法はありません。これは、onmouseoverを調整してonmouseoverを設定できないというだけで、hrefのような副作用のある属性が誤って実行できないという意味ではありません。

その_data:_および_javascript:_ urlプロトコルは他の場所でよく議論されていますが、任意のコンテンツドキュメント(_data:_)およびJSコード(_jacascript:_)にリンクする方法に注意してください。

たとえば、これらの両方をクリックすると、 "666"(獣の印)が警告されます。

Javascript:<a href=javascript:alert(666)>xss</a>

データ:_<a href=data:text/html,%3Cscript%3Ealert%28666%29%3C/script%3E>xss</a>_

どちらもhttp(s)のURLの代わりに使用できるため、コードを実行可能にするためにスラッシュは必要ないため、特に_javascript:_を防ぐようにしてください。

4
dandavis

_JSON.parse_行全体がサーバーで生成されている場合(たとえば、XHRの結果を含む変数で_JSON.parse_を呼び出すのではなく)、一重引用符と二重引用符が許可されている場合(プラス_( )_と_+ - ;_)の少なくとも1つは簡単です。コンテンツは既にスクリプトブロック内で評価されていますが、なぜ発生するのか心配していますスクリプトが終了しますか?それまでに、ペイロードはすでに実行されているはずです!

文字列の連結に_+_を使用したファイル名の例:badfile"'+alert('xss')+'これは完全に意味のない(そして無効な)JSON文字列を生成しますが、気にしないでください。 JSエンジンが文字列を連結しようとすると、_JSON.parse_が呼び出される前に、コードが実行されます(2回)!

_<script>
var foo = JSON.parse('{"x":1,"id":"2","myarr":[{"x1":"1"}],"x2":[{"id1":3,"id2":"15","name":"badfile"'+alert('xss')+'","path":"\/uploads\/pics\/1\/badfile"'+alert('xss')+'","b":"1"}]}')
</script>
_
0
CBHacking