gradual typing embedded securely in javascript

45
GRADUAL TYPING EMBEDDED SECURELY IN JAVASCRIPT Aseem Rastogi University of Maryland, College Park Joint Work With: Nikhil Swamy, Cédric Fournet, Karthikeyan Bhargavan, Juan Chen, Pierre-Yves Strub, Gavin Bierman POPL'14 TS* 1

Upload: stamos

Post on 24-Feb-2016

53 views

Category:

Documents


0 download

DESCRIPTION

Gradual typing Embedded securely in javascript. Aseem Rastogi. University of Maryland, College Park. Joint Work With: Nikhil Swamy , Cédric Fournet , Karthikeyan Bhargavan , Juan Chen, Pierre-Yves Strub , Gavin Bierman. Architecture of JavaScript Applications. Untrusted (e.g. ads). - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Gradual typing Embedded securely in javascript

1

GRADUAL TYPING EMBEDDED SECURELY IN JAVASCRIPT

Aseem RastogiUniversity of Maryland, College Park

Joint Work With:

Nikhil Swamy, Cédric Fournet, Karthikeyan Bhargavan, Juan Chen, Pierre-Yves Strub, Gavin Bierman

POPL'14 TS*

Page 2: Gradual typing Embedded securely in javascript

2

Architecture of JavaScript Applications

POPL'14 TS*

Application

Libraries(e.g. JQuery)

Untrusted(e.g. ads)

Shared Global State(e.g. Object.prototype, String.prototype, Array.prototype)

All scripts execute in the same environment

Page 3: Gradual typing Embedded securely in javascript

3

At Least It’s Dynamically Type Safe

POPL'14 TS*

var x = 0; x(17); ~>* TypeError /* cannot apply a non-function */

Provides some useful security propertiesvar x = 0x1234567; x.f(); ~>* TypeError /* cannot forge an address */

Page 4: Gradual typing Embedded securely in javascript

4

function protect(rawSend) { var whitelist = { “www.microsoft.com/mail” : true, “www.microsoft.com/owa” : true }; return function(url, msg) { if(whitelist[url]) rawSend(msg); }}

Or Is It ?

POPL'14 TS*

function send(url, msg){ /* e.g. XMLHttpRequest */ …}

Object.prototype[“evil.com”] = true;

• Goal : Protect the send message function to restrict malicious URLs

send(“evil.com”, “gotcha”);

Attacker Succeeds !

Also looks up in Object.prototypewindow.send = protect(send);

Page 5: Gradual typing Embedded securely in javascript

5

Type Errors ≈ Security Vulnerabilities

POPL'14 TS*

• Attacker can exploit missing property accesses• Can execute arbitrary JavaScript

Need a stronger notion of type safety !

Page 6: Gradual typing Embedded securely in javascript

6

Stronger Type Safety for JavaScript ?DJS (Chugh et. al.), DJS(Maffeis et. al.), JSVerify(Swamy et. al.), JSVerify(Gardner et. al.), Adsafety(Guha et. al.), SES-light(Taly et. al.), Moller et. al., …

POPL'14 TS*

Handle only subsets of JavaScript

• Cannot ignore the adversary

• Lots of crazy stuff• eval• Proxies• Stack walking• Prototype poisoning• Global namespace corruption• …

Page 7: Gradual typing Embedded securely in javascript

7

Attempts to Handle Full JavaScript ?• TypeScript, Closure• Great in increasing programmer productivity• But Not Type Safe

POPL'14 TS*

Page 8: Gradual typing Embedded securely in javascript

8

We ask …• Can we provide stronger JS type safety

• While accounting for the full ECMAScript5 language• Unrestricted adversary

• And still retaining idiomatic JS programming interface

TS*POPL'14

Page 9: Gradual typing Embedded securely in javascript

9

TS★: Gradual Type System for All of JavaScriptStatically typed core

• number, bool, string• T1 T2 • { fi : Ti } (mutable, extensible) • ADTs

Dynamically typed fragment• any• JSON• Runtime type tests

Un typed adversary• arbitrary JavaScript• unmodified• unverified• unrestricted

Run time checks mediate interactions

TS*POPL'14

U

D S

Page 10: Gradual typing Embedded securely in javascript

10

Key Invariants of TS★

TS*POPL'14

U

D S

Static Safety:Statically typed code is safe without any runtime checks

Dynamic Safety:Runtime types are always refinements of static types

Memory Isolation:No un-location referenced directly in static/any codeNo static/any reference leaked to un-code

Page 11: Gradual typing Embedded securely in javascript

11

Key Idea: Gradual Security

ad.js

lib.js

app.js

function protect(rawSend) { var whitelist = { “www.microsoft.com/mail” : true, “www.microsoft.com/owa” : true }; return function(url, msg) { if(whitelist[url]) rawSend(msg); }}

TS*POPL'14

• Identify security critical code

Page 12: Gradual typing Embedded securely in javascript

12

Key Idea: Gradual Security

ad.js

lib.js

app.js

TS*POPL'14

function protect(rawSend)function protect(rawSend:(string,string)=>any){ var whitelist = { “www.microsoft.com/mail” : true, “www.microsoft.com/owa” : true }; return function(url:string, msg:string) { if(whitelist[url]) rawSend(msg); }}

• Identify security critical code

• Port to TS★

Page 13: Gradual typing Embedded securely in javascript

13

Key Idea: Gradual Security

ad.js

lib.js

app.js

TS*POPL'14

function protect(rawSend)function protect(rawSend:(string,string)=>any){ var whitelist = { “www.microsoft.com/mail” : true, “www.microsoft.com/owa” : true }; return function(url:string, msg:string) { if(whitelist[url]) rawSend(msg); }}

• Identify security critical code

• Port to TS★

function protected() { function protect(rawSend) { … } return wrap<Un>(protect);}window.send = protected();

TS★

• Compile

Page 14: Gradual typing Embedded securely in javascript

14

Key Idea: Gradual Security

ad.js

lib.js

app.js

TS*POPL'14

function protect(rawSend)

• Identify security critical code

• Port to TS★

• Compilefunction protected() { function protect(rawSend) { … } return wrap<Un>(protect);}window.send = protected();

• Drop-in in the app

function protect(rawSend:(string,string)=>any){ var whitelist = { “www.microsoft.com/mail” : true, “www.microsoft.com/owa” : true }; return function(url:string, msg:string) { if(whitelist[url]) rawSend(msg); }}

TS★

Page 15: Gradual typing Embedded securely in javascript

15

Gradual Security – Initial Experience• OWASP CSRFGuard and Facebook API

• Reported many attacks• Both widely used and security critical libraries• Ported critical fragments to TS★

• Easy to argue correctness in the presence of memory isolation

• Secure, High Integrity, and Efficient HTML5 localStorage

POPL'14 TS*

(http://rise4fun.com/FStar/tutorial/tsStar)

Page 16: Gradual typing Embedded securely in javascript

16

TS★ Gradual Typing Overview

POPL'14 TS*

U

D S

Based on runtime type information (RTTI)

Point { x = 2, y = 3 }

type Point = { x:number; y:number }

Compiled as is

Compiled with runtime checks to respect RTTI tags

Library provided wrappers ensure memory isolation

Page 17: Gradual typing Embedded securely in javascript

17

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

TS★ Tour with Example

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

TS*POPL'14

Page 18: Gradual typing Embedded securely in javascript

18

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Compilation of Statically Typed Code

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

TS*POPL'14

function diag(p){ bar(p); p.x = p.y; return p;}

(Statically typed code is safe as is)

Page 19: Gradual typing Embedded securely in javascript

19

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

RTTI Instrumentation

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

TS*POPL'14

diag.rtti = [[Point Point]]

function diag(p){ bar(p); p.x = p.y; return p;}

(Statically typed code is safe as is)

Page 20: Gradual typing Embedded securely in javascript

20

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

RTTI Instrumentation

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

TS*POPL'14

diag.rtti = [[Point Point]]

function diag(p){ bar(p); p.x = p.y; return p;}

(Statically typed code is safe as is)

(Compiled with runtime type checks)

Page 21: Gradual typing Embedded securely in javascript

21

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Runtime Checks on RTTI (Dynamic Safety)

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

any { x = true }

o:

TS*POPL'14

Page 22: Gradual typing Embedded securely in javascript

22

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Runtime Checks on RTTI (Dynamic Safety)

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

any { x = true }

o:

Is o a record ? Does o.x = 2 respect o’s rtti ? ✔

any { x = 2 }

o:

TS*POPL'14

Page 23: Gradual typing Embedded securely in javascript

23

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Runtime Checks on RTTI (Dynamic Safety)

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

any { x = true }

o:

Is o a record ? Does o.y = 3 respect o’s rtti ? ✔

any { x = 2 }

o:

any { x = 2, y = 3 }

o:

TS*POPL'14

Page 24: Gradual typing Embedded securely in javascript

24

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Dynamically Typed to Statically Typed

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

any { x = 2, y = 3 }

o:

TS*POPL'14

Page 25: Gradual typing Embedded securely in javascript

25

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Attempt 1 : Use Higher Order Casts for Mutable Records

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

TS*POPL'14

var o’ ={ get x() { if hasOwnProperty(o, “x”) … }; get y() { … }; set x(v) { … }; set y(v) { … };}diag(o’);

Page 26: Gradual typing Embedded securely in javascript

26

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Problems with Higher Order Casts

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

TS*POPL'14

var o’ ={ get x() { … }; get y() { … }; set x(v) { … }; set y(v) { … };}diag(o’);

1. Lazy failures in statically typed code• Undesirable for security critical applications• Performance penalty for casts reduction

2. Space inefficient• Might recover with fancy coercion reductions

3. Breaks object identity• o === o’ ?

Page 27: Gradual typing Embedded securely in javascript

27

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Gradual Typing with RTTI

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

TS★

JS

any { x = 2, y = 3 }

o:

Does o look like a Point ? If so, tag it. (setTag)

Point { x = 2, y = 3 }

o, p:

TS*POPL'14

Page 28: Gradual typing Embedded securely in javascript

28

Monotonic Evolution of RTTI

POPL'14 TS*

t0

v0t2

v2t1

v1tn

vn

v0:t0

v1:t1

v2:t2 vn:tn

RTTI is always a sound approximation of a runtime value

RTTI evolves monotonically w.r.t the subtyping relation

t0 :> t1 :> t2 :> … :> tn

Page 29: Gradual typing Embedded securely in javascript

29

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

function bar(q){ q.x = true;}

Seamless Transition from Statically Typed to Dynamically Typed

TS★

JS

Seamless via subtyping – Point <: any.

Point { x = 2, y = 3 }

o, p:

TS*POPL'14

Page 30: Gradual typing Embedded securely in javascript

30

function bar(q){ q.x = true;}

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

RTTI Violations Cause Runtime Failures

TS★

JS

Point { x = 2, y = 3 }

o, p, q:

Is q a record ? Does q.x = true respect q’s rtti ? ✗ Runtime failure

TS*POPL'14

Page 31: Gradual typing Embedded securely in javascript

31

function bar(q){ q.color = “red”;}

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

Runtime Checks on RTTI (Dynamic Safety)

TS★

JS

Point { x = 2, y = 3 }

o, p, q:

Is q a record ? Does q.color = “red” respect q’s rtti ? ✔

Point { x = 2, y = 3, color = “red” }

o, p, q:

TS*POPL'14

Page 32: Gradual typing Embedded securely in javascript

32

function bar(q){ q.color = “red”;}

type Point = { x:number; y:number }

function diag(p:Point) : Point{ bar(p); p.x = p.y; return p;}

var o = { x : true };o.x = 2; o.y = 3;

diag(o);

Statically Typed Code Executes As Is

TS★

JS

Point { x = 2, y = 3, color = “red” }

o, p, q:

Executes as expected, without any checks.

TS*POPL'14

Page 33: Gradual typing Embedded securely in javascript

33

Key Invariants of TS★

TS*POPL'14

U

D S

Static Safety:Statically typed code is safe without any runtime checks

Dynamic Safety:Runtime types are always refinements of static types

Memory Isolation:No un-location referenced directly in static/any codeNo static/any reference leaked to un-code

Page 34: Gradual typing Embedded securely in javascript

34

type Point = { x:number; y:number }

function diag(p:Point) : Point{ baz(p); p.x = p.y; return p;}

function baz(q){ …}

Memory Isolation from Un

TS★

JS

Unmodified, unverified, unrestricted.

TS*POPL'14

Page 35: Gradual typing Embedded securely in javascript

35

type Point = { x:number; y:number }

function diag(p:Point) : Point{ baz(p); p.x = p.y; return p;}

function baz(q){ delete q.x; }

Memory Isolation from Un

TS★

JS

Unmodified, unverified, unrestricted.

TS*POPL'14

function baz(q){ delete q.rtti; }

function baz(q){ q.rtti = “junk”; }

How to protect invariants ?

Page 36: Gradual typing Embedded securely in javascript

36

type Point = { x:number; y:number }

baz : Un

function diag(p:Point) : Point{ baz(p); p.x = p.y; return p;}

function baz(q){ …}

Memory Isolation from Un

TS★

• A second dynamic type Un

• Abstract type: not related to any other type

• Point <: any <\: Un

• { f : number; g : Un } <: { g : Un } <\: { }

TS*POPL'14

Page 37: Gradual typing Embedded securely in javascript

37

type Point = { x:number; y:number }

baz : Un

function diag(p:Point) : Point{ baz(p); p.x = p.y; return p;}

function baz(q){ …}

Memory Isolation from Un

TS★

Compile error: Cannot apply an Un typed term

TS*POPL'14

Page 38: Gradual typing Embedded securely in javascript

38

type Point = { x:number; y:number }

baz : Un

function diag(p:Point) : Point{ wrap<Un, Point any>(baz)(p); p.x = p.y; return p;}

function baz(q){ …}

Memory Isolation from Un

TS★

Library provided wrappers, ensure memory isolation

TS*POPL'14

Page 39: Gradual typing Embedded securely in javascript

39

Wrappers Enforce Heap Shape Invariant

POPL'14 TS*

un fragmentStatic and any-typed DMZ(stubs)

• Non-Un values completely independent of untrusted global state (prototypes etc.) – thus send/protect example is secure in TS★

• TS★ runtime system needs “first starter privileges” on the page

Page 40: Gradual typing Embedded securely in javascript

40

Facebook API Example

POPL'14 TS*

Untrusted web page Facebook API

Iframe

Retrieves user’s access token

Gives access token to the untrusted page if it’s authorized by user

Wants to connect to Facebook on current user’s credentials

Page 41: Gradual typing Embedded securely in javascript

41

Facebook API Sample Code

POPL'14 TS*

function decode(s){ var res = { }; if(s === “”) return res; var p = String.split(s,“&”); for(var k in p) { var kv = String.split(p[k],“=“); res[kv[“0”]] = kv[“1”]; } return res;}

function checkOrigins(g, e){ for(var k in e) { if(g === e[k]) return true; } return false;}

Page 42: Gradual typing Embedded securely in javascript

42

Example Vulnerabilities in Facebook API

POPL'14 TS*

function checkOrigins(g, e){ for(var k in e) { if(g === e[k]) return true; } return false;}

Attacks similar toprotect/send(Using Object.prototype)

function decode(s){ var res = { }; if(s === “”) return res; var p = String.split(s,“&”); for(var k in p) { var kv = String.split(p[k],“=“); res[kv[“0”]] = kv[“1”]; } return res;}

Page 43: Gradual typing Embedded securely in javascript

43

function decode(s:string):any{ var res = { }; if(s === “”) return res; var p = String.split(s,“&”); for(var k in p) { var kv = String.split(p[k],“=“); res[kv[“0”]] = kv[“1”]; } return res;}

Porting Facebook API to TS★

POPL'14 TS*

function checkOrigins(g:string, e:array string):bool{ for(var k in e) { if(g === e[k]) return true; } return false;}

Page 44: Gradual typing Embedded securely in javascript

44

Also in the paper …• More details on the wrappers• Formal translation from TS★ to JavaScript• Formalization of TS★ in JSVerify†

• Type soundness theorem and proof sketch• A standards based mechanism for first starter privileges• More examples

†Swamy et. al. PLDI’ 13

See our paper !

TS*POPL'14