AngularJSテンプレートサンドボックスをエスケープできるバグを見つけました。 Angularは口ひげベースのテンプレート言語です。 HTMLで評価される式を配置できます。たとえば、{{1 + 1}}は2でレンダリングされます
サンドボックスにより、ユーザーは式内のAngular内からウィンドウ/コンストラクターにアクセスできなくなります。たとえば、{{{}。constructor = ...}}は実行できません。これは、サイトがユーザー入力からテンプレートも保存している場合、これらの操作は安全ではないと見なされるためです。 XSSにサイトを開きます。
ソースコードを確認すると、バイパスできるobj === {} .constructorのチェックがあることがわかりました。
基本的には、これを回避することになります。
if (obj) {
if (obj === (0).constructor || obj === (false).constructor || obj === ''.constructor ||
obj === {}.constructor || obj === [].constructor || obj === Function.constructor) {
throw $parseMinErr('isecaf',
'Assigning to a constructor is disallowed! Expression: {0}', fullExpression);
}
}
コンストラクターの呼び出しを別のオブジェクト(オブジェクトリテラルまたは配列リテラル)内に隠すことで、これらのチェックを回避することができました。
リテラルオブジェクトとして:
{{x = {'y':''.constructor.prototype}; x['y'].charAt=[].join;$eval('x=alert(`Evaluated Object Literal`)');}}
または配列として:
{{x = [''.constructor.prototype]; x[0].charAt=[].join; $eval('x=alert(`Evaluated Array`)');}}
上記のチェックを改善して、これらのケースが失敗するようにするにはどうすればよいですか?
代わりにobj === {} .constructorチェックをinstanceofに変更してみましたが、チェックが機能しますが、独自のセキュリティ問題が発生する可能性があると思います。プルリクエストを送信したいのですが、サンドボックスをできるだけ強くするために、他のセキュリティ研究者が会話に貢献してくれることを期待しています。
これは、参照用にAngularプロジェクトに投稿された私の問題です: https://github.com/angular/angular.js/issues/14939
ここに関連資料があります: http://blog.portswigger.net/2016/01/xss-without-html-client-side-template.html
ここにjsFiddleがあります: https://jsfiddle.net/ianhickey/5sb665we/
Angular users:UNSANITIZED User Inputの保存を停止します。
自分の質問に対する答えについては、さまざまな感情があります。 Angularバージョン1.6以降、Angularチームは、サンドボックスを完全に削除することを決定しました。サンドボックス(完全ではありません)は、ユーザーに表面的なレベルの保護を提供しましたAngularアプリを構築するときの独自の選択に対して。サンドボックスは本当にかなり良くなり、どんどん良くなっています。しかし、サンドボックスも決して意図されていませんセキュリティの境界となるため、クリーンな設計の原則を実施するための試みがありました。
サンドボックスがなくなると、Angularユーザーは、信頼されていない、サニタイズされていない、ユーザー入力を保存することのセキュリティへの影響について考えざるを得なくなります。私が個人的には良いことだと思います。このアップグレードにより、以前は無視されていたより広いセキュリティの問題が発生する可能性があることに気づいた場合にのみ、この投稿が「angular 1.6 security」を検索しているときの気づきを高めるのに役立ちます。
この質問に対する答えは、Angularは1.6の時点でサンドボックスを削除して、ユーザーがサンドボックスを意図しないセキュリティメカニズムとして使用していたという事実に対処するためです。