Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

23
Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds PRESENTED BY Nera Liu and Adonis FungMay 21, 2015

Transcript of Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Page 1: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Frontend Security: Applying Contextual Escaping Automatically, orHow to Stop XSS in Seconds

PRESENTED BY Nera Liu and Adonis Fung⎪ May 21, 2015

Page 2: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Problem Statement

What makes XSS prevention so hard?

Background > Related Work > Our Approach > Evaluations > Conclusion

Page 3: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

XSS Quick Explanation

Given no proper output filtering:<h1>Hello <?php echo $_GET['name']; ?></h1>

An attack vector can come through the query string at victim.com/?name=XXX, where XXX is:

"'><script>alert(1)</script>

HTML of victim.com ends up being:<h1>Hello "'><script>alert(1)</script></h1>

Page 4: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Cross-Site Scripting (XSS)

Root Cause- Untrusted inputs executed as scripts under a victim’s origin/domain

Consequences- Cookie stealing, privacy leaking- Fully control the web content- Bug bounty costs

Page 5: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Cross-Site Scripting (XSS)

■ Ranked No. 3 / OWASP Top 10 WebApp Security Risks

Screen-captured from https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_(XSS)

Page 6: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

XSS Defenses

Defense-in-depth:- Prevent, Detect, Contain, etc...

Generally, apply output filtering to prevent XSS- Blindly-escape sensitive chars (e.g., & < > " ' `)

- PHP: htmlentities(untrusted_data)

- JavaScript: untrustedData.replace(/[&<>"'`]/, ...)

- Templating: {{untrustedData}} is blindly-escaped by default

Page 7: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Blindly-escaping is still vulnerable!

Blindly-escaping (&<>"'`) would not stop XSS, when- {{url}} is an untrusted user input (assumed thereafter)- {{url}} is javascript:alert(1), or- {{url}} is # onclick=alert(1)

→ We need Contextual Escaping!- While blindlyEscape( data ) works, but not for url- blacklistProtocol( escapeUnquoted ( encodeURI( url ) ) )

A template is typically written like so:<a href={{url}}>{{data}}</a>

Page 8: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

XSS Output Filtering

Contextual-escaping Filters (Secure)

Blindly-escaping Filters (Vulnerable)

Manual(error-prone and

doesn’t scale)

Automatic(defaulted by

template engines) ✔✘

Page 9: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Related Work

Limited solutions/attempts available- Use Closure/AngularJS w/Strict Contextual Escaping- Use XML Templates with Java/JSP- Without Contextual Escaping: React, Dust, etc...

Deployability/Adoption Issues- Framework specific- Browser compatibility issues- Not for existing projects, unless requiring many code changes

Page 10: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Highlights- Efficient HTML 5 compliant parser w/auto corrections- Auto apply contextual, just-sufficient, and faster escaping- Effortless adoption requiring as little as 2 LoC changes

https://yahoo.github.io/secure-handlebars

Our Approach: Secure Handlebars

Automatic contextual escaping made easy

Page 11: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Handlebars

Context Parser

Handlebars PreProcessor

High-level Architecture

Template Parser

Template AST

HTML5 Parser (w/auto corrections)

JS Parser

AST Walker

Template w/filter markups

abstracting branching logics and output expressions

CSS Parser

Pre-compiler

Contextual XSS Filters(registered as helpers/callbacks)

HTML

Data(possibly untrusted)

Runtime Compiler

Template Spec.

Our solution comprises of only the blue boxes

Page 12: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Handlebars

Context Parser

Handlebars PreProcessor

High-level Architecture

Template Parser

Template AST

HTML5 Parser (w/auto corrections)

JS Parser

AST Walker

Template w/filter markups

abstracting branching logics and output expressions

CSS Parser

Pre-compiler

Contextual XSS Filters(registered as helpers/callbacks)

HTML

Data(possibly untrusted)

Runtime Compiler

Template Spec.

Our solution comprises of only the blue boxes

Page 13: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Pre-Processor: Good Template Samples[Before]

<a href="{{url}}">{{url}}</a>

[After]

<a href="{{{yubl (yavd (yufull url))}}}">{{{yd url}}}</a>

Add contextual escaping filters {{{ }}} - disable the default blindly-escaping yufull - encodeURI() with IPv6 support yavd - html-escape double-quote character (" → &quot;) yubl - disable dangerous protocols such as javascript: yd - html-escape less-than character (< → &lt;)

Page 14: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Pre-Processor: Bad Template Samples[Before]

<input type="button" onclick="doSth({{data}})">

Warning!

Ensure placeholders are never put in scriptable contexts- Security anti-pattern to place (possibly) untrusted data in executable contexts- Workaround:

- <input type="button" data-sth="{{data}}" onclick="doSth(this.getAttribute('data-sth'))">

Page 15: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Pre-Processor: Branching Consistency Check[Before]{{#if highlight}}<strong>{{else}}<em {{/if}} {{unknownCxt}} ...

[After] A warning is raised!

{{#if highlight}}<strong>{{else}}<em {{/if}} {{data}} ...

Walk through branches & ensure they end up in identical state/context- Likely a careless mistake or typo- Obviously, context of {{unknownCxt}} is ambiguous

Warning!

Page 16: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Handlebars

Context Parser

Handlebars PreProcessor

High-level Architecture

Template Parser

Template AST

HTML5 Parser (w/auto corrections)

JS Parser

AST Walker

Template w/filter markups

abstracting branching logics and output expressions

CSS Parser

Pre-compiler

Contextual XSS Filters(registered as helpers/callbacks)

HTML

Data(possibly untrusted)

Runtime Compiler

Template Spec.

Our solution comprises of only the blue boxes

Page 17: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Standard Compliant- Can even auto-correct parse errors to enforce

consistent parsing across browsers

Robust, lightweight, and efficient- Simplified state transitions- No unnecessary handling (no DOM)

Design Principles of Context Parser

Figured from Overview of HTML 5 Parsing Model: https://html.spec.whatwg.org/multipage/syntax.html#overview-of-the-parsing-model

Page 18: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Handlebars

Context Parser

Handlebars PreProcessor

High-level Architecture

Template Parser

Template AST

HTML5 Parser (w/auto corrections)

JS Parser

AST Walker

Template w/filter markups

abstracting branching logics and output expressions

CSS Parser

Pre-compiler

Contextual XSS Filters(registered as helpers/callbacks)

HTML

Data(possibly untrusted)

Runtime Compiler

Template Spec.

Our solution comprises of all blue boxes

Page 19: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Design Principles of XSS Filters

Context-aware- More Secure - escape only

those that can break out from its context

Just sufficient encoding- Faster - no need to

escape all & > " ' `- More friendly - no more

double-encoding issues like &amp;lt;

Page 20: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Deployability

Adoption- Switch from express-handlebars to express-secure-handlebars npm

- 2 LOCs changes: (1) dependency in package.json, (2) require(...)- Alternatively, a more decoupled approach:

- pre-process tmpl to get it rewrited during build process at server- only register helpers for data filtering and binding at client-side

Browser Compatibility- IE 7+, Safari 5+, Chrome, Firefox

Page 21: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Evaluations

Deployed in one the largest properties- Negligible offline overhead

- takes <3s to analyze/pre-process 880 templates- Insignifiant runtime overhead (i.e., filter callbacks, size: 1.3KB gz)

- unchained filters: up to 2 times faster than default- chained filters: slower but is already minimal to be secure

- True positives found! - e.g., unquoted, onclick, URI attributes, script tags, etc.

Page 22: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

- More secure, efficient, and easier adoption- Open-sourced at github.com/yahoo and npmjs.com- Contact/Collaborate with us for more template support

Conclusion: Building A Safer Internet for All

Automatic contextual escaping made easy

Page 23: Frontend Security: Applying Contextual Escaping Automatically, or How to Stop XSS in Seconds

Thank you!

Nera, Albert, Adon{neraliu, albertyu, adon}@yahoo-inc.

comTwitter: @neraliu, @yukinying, @adonatwork