web-dev-qa-db-ja.com

無害化されたユーザー入力でdocument.writeを悪用する

JavaScriptをjsスクリプトファイルに挿入しようとしていますが、機能しません。

次の設定があります。

javascript-file includeを含むhtmlファイル(すべてのインラインjsがブロックされます!)

Welcome, <script src="js/domxss.js" type="text/javascript"></script>

js/domxss.jsのjavascriptソース:

var pos=document.URL.indexOf("user=")+5;
var userInput=document.URL.substring(pos,document.URL.length);
document.write(unescape(userInput));

明らかに私はちょうど要求できます

domain.com/index.html?user=<script>alert(1)</script> 

そしてそれは実行されますが、すべてのインラインjsは私のContent-Security-Policyによってブロックされています。だから私がやろうとしているのは抜け出すことです

document.write((userInput));

このようなもので:

domain.com/index.html?user=bob); alert(1

私はこのようなものを得ることができるように:

document.write(bob);alert(1);

誰かが私がそれをどのように達成できるかについてのアイデアを持っていますか?私はdocument.writeに縛られていません。インラインコードとして出力するのではなく、スクリプトファイルにJSを直接挿入できるDOMベースのXSSの例を探しています。

基本的な質問のようですが、私はJSにそれほど詳しくありません。

助けてくれてありがとう :)

1
mohrphium

簡単に言えば、ペイロードbob); alert(1は文字列であり、JavaScriptはその文字列を認識しているため実行できません。括弧とセミコロン文字は、実行せずに文字列の中に入れることができます。たとえば、ペイロードをeval()ステートメントに連結しようとした場合、このコードは脆弱になる可能性があります。これは、evalが結果の文字列内でコードを実行するためです。

_var pos=document.URL.indexOf("user=")+5;
var userInput=document.URL.substring(pos,document.URL.length);
eval("document.write('" + decodeURI(userInput) + "');");
_

次にdomain.com/index.html?user=bob');%20alert('1を実行すると、次の文字列がJavaScriptとして実行されます。

_document.write('bob'); alert('1');
_

これがeval()が一般的に悪い考えである理由です

ただし、適切なContent-Security-Policyはおそらくeval()でのユーザー入力もブロックするため、このメソッドは機能しない可能性があります。これは、サーバーから返されるポリシーに依存します。または、ポリシーが指定されていない場合にブラウザーがロードするデフォルトのコントロールです。


eval()の代替

開発者がサニタイズまたは検証なしにユーザー制御可能なデータを誤って評価する可能性のある他の危険な方法(つまり、デフォルトのCSPまたはクライアント側のXSSフィルターによってmightがキャッチされない)。

関数コンストラクター(関数本体を文字列として定義できます):

_var pos=document.URL.indexOf("user=")+5;
var userInput=document.URL.substring(pos,document.URL.length);
var terribleFunction = new Function( "document.write('" + decodeURI(userInput) + "');" );
terribleFunction();
_

A データURI

_var pos=document.URL.indexOf("user=")+5;
var userInput=document.URL.substring(pos,document.URL.length);
var terribleScript = document.createElement('script');
terribleScript.src = 'data:text/javascript,' + encodeURIComponent("document.write('" + decodeURI(userInput) + "');");
document.body.appendChild( terribleScript );
_

setTimeout(このメソッドは基本的にeval()と同じだと思いますが):

_var pos=document.URL.indexOf("user=")+5;
var userInput=document.URL.substring(pos,document.URL.length);
setTimeout( "document.write('" + decodeURI(userInput) + "');" , 100 );
_
2
itscooper