trusted types and the end of dom xss

35
Trusted Types and the end of DOM XSS

Upload: others

Post on 02-Nov-2021

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Trusted Types and the end of DOM XSS

Trusted Types and the end of DOM XSS

Page 2: Trusted Types and the end of DOM XSS

Google Vulnerability Reward Program payouts in 2018

XSS 35.6%

Non-web issues 49.1%

Mobile app vulnerabilitiesBusiness logic (authorization)Server /network misconfigurations...

2

Page 3: Trusted Types and the end of DOM XSS

Source: HackerOne report, 2018

Consumer Goods

Financial services & insurance Government Healthcare Media &

EntertainmentProfessional

servicesRetail &

EcommerceTechnology Telecom Transportation Travel &

Hospitality

Figure 5: Listed are the top 15 vulnerability types platform wide, and the percentage of vulnerabilities received per industry

Cross Site scripting (XSS)

Information disclosure

Improper authentication

Violation of secure design principles

Cross-site request forgery (CSRF)

Open redirect

Privilege Escalation

Improper access control

Cryptographic issues

Denial of service

Business logic errors

Code injection

SQL injection

Vulnerabilities by industry

3

Page 4: Trusted Types and the end of DOM XSS

Paid bounties by vulnerabilityon Mozilla websites in 2016 and 2017

Source: @jvehent, Mozilla

Coun

t of V

ulne

rabi

lity

wsec-xss

wsec-applogic

wsec-disclosure

wsec-impersonatio

n

wsec-objref

wsec-injectio

n

wsec-appmisconfig

wsec-authenticatio

n

wsec-redire

ct

wsec-oscmd

wsec-http-header-in

ject

wsec-serverm

isconfig

wsec-sqli

wsec-authorizatio

n

wsec-crossdomain

wsec-csrf

4

Page 5: Trusted Types and the end of DOM XSS

Why do we still have DOM XSS?

Easy to introduce

Hard to detect

&

5

Page 6: Trusted Types and the end of DOM XSS

DOM XSS is a client-side XSS variant caused by the DOM API not being secure by default.

● User controlled strings get converted into code● via dangerous and error-prone DOM sinks like innerHTML

var foo = location.hash.slice(1);

document.querySelector('#foo').innerHTML = foo;

How does DOM XSS happen?

Example: https://example.com/#<img src=x onerror=alert('xss')>

6

Page 7: Trusted Types and the end of DOM XSS

Element.innerHTML

Page 8: Trusted Types and the end of DOM XSS

Element.innerHTML

8

HTMLFormElement.action

window.open

HTMLAreaElement.href

HTMLMediaElement.src

HTMLFrameElement.src

HTMLSourceElement.src

HTMLTrackElement.src

HTMLInputElement.src

location.assign

location.hrefdocument.write

HTMLButtonElement.formAction

HTMLFrameElement.srcdoc

HTMLImageElement.srcHTMLEmbededElement.src

HTMLScriptElement.textContent

HTMLInputElement.formAction

HTMLScriptElement.InnerText

HTMLBaseElement.href

Page 9: Trusted Types and the end of DOM XSS

Is this DOM XSS?

9

foo.innerHTML = location.href

Page 10: Trusted Types and the end of DOM XSS

foo.innerHTML = bar

Is this DOM XSS?

10

foo.innerHTML = location.href

Page 11: Trusted Types and the end of DOM XSS

foo.innerHTML = bar

Is this DOM XSS?

11

foo.innerText = bar

foo.innerHTML = location.href

Page 12: Trusted Types and the end of DOM XSS

foo.innerHTML = bar

Is this DOM XSS?

12

foo.innerText = bar

foo.innerHTML = location.href

foo[baz] = bar

Page 13: Trusted Types and the end of DOM XSS

Growing problem● DOM sinks can be used by your own code

○ … or the libraries you use○ … or the scripts you load (analytics?)○ … or the script that they load at runtime.

● Each of those potentially introduces DOM XSS

● Static analysis for JS does not work reliably

● At Google, DOM XSS is already the most common XSS variant.

13

Page 14: Trusted Types and the end of DOM XSS

To fix DOM XSS we need toreduce the attack surface

and make security decisions explicit

14

Page 15: Trusted Types and the end of DOM XSS

We know how to address it!Safe Types (link)

● 6+ years of experience● Protects Gmail and almost all other

Google applications● Evidence of efficacy● Securely produce values that end up in DOM

● Implemented as Java{Script},Go, … libraries● We're porting this approach directly to the browsers

15

Page 16: Trusted Types and the end of DOM XSS

Trusted Types

16

Page 17: Trusted Types and the end of DOM XSS

Strongly typed DOM API.

● Don't pass (HTML, URL, script URL) strings to the DOM sinks● Use objects instead● DOM already supports it:

● Web platform (or polyfill) provides typed objects:TrustedHTML, TrustedScript, TrustedScriptURL

● Security rules & controls are based on types

The idea behind Trusted Types

el.innerHTML = {toString: () => 'hello'};

el.innerHTML // 'hello'

17

Page 18: Trusted Types and the end of DOM XSS

When Trusted Types are not enforced:

DOM sinks accepts strings as usual

DOM sinks accept typed objects

element.innerHTML = aTrustedHTML

The idea behind Trusted Types

element.innerHTML = location.hash.slice(1) // a string

18

Page 19: Trusted Types and the end of DOM XSS

When Trusted Types are enforced:

DOM sinks reject strings

DOM sinks accept typed objects

Content-Security-Policy: trusted-types myPolicy

element.innerHTML = location.hash.slice(1) // a string

element.innerHTML = aTrustedHTML

The idea behind Trusted Types

19

Page 20: Trusted Types and the end of DOM XSS

When Trusted Types are in reporting mode:

DOM sinks accept & report strings

DOM sinks accept typed objects

Content-Security-Policy-Report-Only: trusted-types myPolicy; report-uri /report

element.innerHTML = location.hash.slice(1) // a string

element.innerHTML = aTrustedHTML

The idea behind Trusted Types

20

Page 21: Trusted Types and the end of DOM XSS

1. Create policies with validation rules

Creating Trusted Types

const SanitizingPolicy = trustedTypes.createPolicy('myPolicy', {

createHTML(s: string) => myCustomSanitizer(s)

}, false);

21

Page 22: Trusted Types and the end of DOM XSS

1. Create policies with validation rules

2. Use the policies to create Trusted Type objects

Creating Trusted Types

const SanitizingPolicy = trustedTypes.createPolicy('myPolicy', {

createHTML(s: string) => myCustomSanitizer(s)

}, false);

// Calls myCustomSanitizer(foo).

const trustedHTML = SanitizingPolicy.createHTML(foo);

element.innerHTML = trustedHTML;

22

Page 23: Trusted Types and the end of DOM XSS

1. Create policies with validation rules

2. Use the policies to create Trusted Type objects

3. Enforce "myPolicy" by setting a Content Security Policy header

Creating Trusted Types

Content-Security-Policy: trusted-types myPolicy myOtherPolicy

const SanitizingPolicy = trustedTypes.createPolicy('myPolicy', {

createHTML(s: string) => myCustomSanitizer(s)

}, false);

// Calls myCustomSanitizer(foo).

const trustedHTML = SanitizingPolicy.createHTML(foo);

element.innerHTML = trustedHTML;

23

Page 24: Trusted Types and the end of DOM XSS

The "default" policy is called as a fallback when a string is assigned to a sink.

Good way to get started and to identify risky DOM assignments.

Trusted Types - default policy

Content-Security-Policy: trusted-types myPolicy default

trustedTypes.createPolicy('default', {

createHTML(s) {

console.log("Please fix! Insecure string assignment: ", s);

return s;

// Only return if you're OK with a value.

}

});

24

Page 25: Trusted Types and the end of DOM XSS

The "default" policy will be used when navigating to javascript: URLs.

By default, javascript: URLs stop working, but custom rules can be added.

Trusted Types - default policy

trustedTypes.createPolicy('default', {

createScript(s) {

if (s === 'void(0)') { // Allowing javascript:void(0)

return s;

}

return; // … and nothing else.

}

});

25

Page 26: Trusted Types and the end of DOM XSS

1. Add Trusted Types to libraries that write to the DOM2. Verify that your code uses only those libs (grep, linters, compiler plugins, …)3. Add Content-Security-Policy-Report-Only: trusted-types *4. Observe violations, debug5. goto 2 :)6. Enforce Trusted Types

Trusted Types - a deployment strategy

26

Page 27: Trusted Types and the end of DOM XSS

DEMO

27

Page 28: Trusted Types and the end of DOM XSS

DEMO

28

Page 29: Trusted Types and the end of DOM XSS

Control policy creation:

● Policy name whitelist:

● No duplicate policy names

Control policy usage:

● Policies are JavaScript objects● Lock them in a module, inside a local function variable etc.

Control over policies

Content-Security-Policy: trusted-types myPolicy myOtherPolicy

29

Page 30: Trusted Types and the end of DOM XSS

Control over policies(function() {

// Seemingly unsafe policy

const unsafePolicy = trustedTypes.createPolicy('main-component', {

createHTML: (s) => s,

});

// No XSS because of the usage limitation

unsafePolicy.createHTML(`<div>My application component<div>`)

})();

30

Page 31: Trusted Types and the end of DOM XSS

Benefits

Source ... Policy Trusted Type→ → → ... DOM sink→

● Reduced attack surface - The risky data flow will always be:

● Isolates security-sensitive code from the rest of the applications● No DOM XSS if policies are secure and access restricted

● Compile time & runtime security validation● Gradual adoption possible

31

Page 32: Trusted Types and the end of DOM XSS

DOMPurify

React

More at github.com/w3c/webappsec-trusted-types/wiki/Integrations

Integration examples

32

DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true })

$ git clone https://github.com/facebook/react

$ cd react

$ yarn

Set enableTrustedTypesIntegration = true in ReactFeatureFlags.js

$ yarn build react/index,react-dom/index --type=UMD

Page 33: Trusted Types and the end of DOM XSS

● Active development, looking for your feedback!● Support in Chromium browsers

--enable-blink-features=TrustedDOMTypes● Discussion group - [email protected] ● W3C specification draft - w3c.github.io/webappsec-trusted-types/ ● Polyfills & documentation at bit.ly/trusted-types

Project status

33

Page 34: Trusted Types and the end of DOM XSS

Try Trusted Types now!bit.ly/trusted-types

34

Page 35: Trusted Types and the end of DOM XSS

THANKS FOR ATTENTION!

@kkotowicz

35