36
A Two-Tier Sandbox Architecture for Untrusted JavaScript Phu H. Phung Chalmers University of Technology JSTools’ 12 June 13, 2012, Beijing, China Joint work with Lieven Desmet (KU Leuven)

A Two-Tier Sandbox Architecture for Untrusted JavaScript

Embed Size (px)

DESCRIPTION

JSTools'12 13 June, 2012 Beijing, China

Citation preview

Page 1: A Two-Tier Sandbox Architecture for Untrusted JavaScript

A Two-Tier Sandbox Architecture for Untrusted JavaScript

Phu H. PhungChalmers University of Technology

JSTools’ 12June 13, 2012, Beijing, China

Joint work with Lieven Desmet (KU Leuven)

Page 2: A Two-Tier Sandbox Architecture for Untrusted JavaScript

2

Untrusted JavaScript

External third-party JS code embedded to hosting pages, e.g., ads, widgets, analysis tools Run with the same privilege of the

hosting page Security issues:

Malicious third-party code Trusted third-party is compromised Confidentiality, integrity, and other

security risks

Page 3: A Two-Tier Sandbox Architecture for Untrusted JavaScript

3

Approaches for untrusted JavaScript

Server-side pre-processing of untrusted code to ensure the code is in a safe subset Transformation, e.g. Caja, BrowserSheild Code validation, e.g. Adsafe

Iframe isolation e.g., Adjail, Webjail

Behavioral sandboxing Browser modification, e.g. ConScript Client-side security wrappers

Lightweight Self-

Protecting JavaScript

Page 4: A Two-Tier Sandbox Architecture for Untrusted JavaScript

4

Outline

Context Overview of Self-Protecting

JavaScript Goals Two-tier sandbox architecture Technical approach Validation Summary and further work

Page 5: A Two-Tier Sandbox Architecture for Untrusted JavaScript

5

Lightweight Self-Protecting JavaScript (SPJS)

Intercept JavaScript security-relevant actions with policies by wrappers control or modify the bad behaviour

The method works since we only try to control built-in calls

Page 6: A Two-Tier Sandbox Architecture for Untrusted JavaScript

6

Advantages of SPJS

Easy of deployment No browser modification nor user

installation Non-invasive: no difficulties with dynamic-

generated JavaScript code Focus on code behavior, not code

integrity does not parse or transform the code

Can enforce application-specific, fine-grained policies at runtime, e.g.: limit the number of popup to 3 Disallow send after cookie read

Page 7: A Two-Tier Sandbox Architecture for Untrusted JavaScript

7

SPJS with Untrusted JavaScript

Self-Protecting JavaScript Code TRUSTED

UNTRUSTED

No privilege distinguish between hosting code and external code

Hosting codeHosting

codeHosting

code

external code

external code

Page 8: A Two-Tier Sandbox Architecture for Untrusted JavaScript

8

Goals

Deploy SPJS in the context of untrusted JS Load and execute untrusted code

without pre-processing the code No browser modification is required

Enforce modular and fined-grained, stateful security policies for a piece of untrusted code Protect the hosting page from untrusted

code Robust to potential flaws in security

policies Bad written policies might not break

security

Page 9: A Two-Tier Sandbox Architecture for Untrusted JavaScript

9

Sandboxing untrusted code

Use Secure ECMAScript (SES) library developed by Google Caja team (Miller et al) Load a piece of code to execute within

an isolated environment▪ The code can only interact with the outside

world via a provided APIvar api = {...}; //constructingvar makeSandbox = cajaVM.compileModule(untrustedCodeSrc);var sandboxed = makeSandbox(api);

Page 10: A Two-Tier Sandbox Architecture for Untrusted JavaScript

10

Policy definition approaches API implementation

Can enforce coarse-grained, generic policies, e.g.:▪ Sanitize HTML▪ Ensure complete mediation

More fine-grained policies are needed for multiple untrusted code Modular, principal-specific, e.g.: script1 is allowed to

read/write reg_A, script2 is allowed to read reg_A Stafeful, e.g.: limit the number of popups to 3 Cross-principal stateful policies, e.g: after script1

write to reg_A, disallow access from script2 to reg_A

Page 11: A Two-Tier Sandbox Architecture for Untrusted JavaScript

Policy code within API code

API/policy 2API/policy 1

untrusted

API/policy 3

untrusted

untrusted

• API implementation is complex,

• difficult and error-prone to specify application-specific policy within API

11/40

Page 12: A Two-Tier Sandbox Architecture for Untrusted JavaScript

12

Two-tier sandbox architecturevar api = loadAPI(api_url);

var outerSandbox = cajaVM.compileModule(policyCode);

var enforcedAPI = outerSandbox(api);

var innerSandbox = cajaVM.compileModule(untrustedCode);

innerSandbox(enforcedAPI);

Page 13: A Two-Tier Sandbox Architecture for Untrusted JavaScript

13

Sandbox running

untrusted code, defined in a separate file

e.g. `untrusted.js’

Sandbox running policy code, defined in a separate file e.g. `policy.js’

Base-line API implementation,in e.g. `api.js’ file

JavaScript environme

nt, e.g. the

DOM

The policy code can only access the base-line API and provided

wrapper functions (ensuring no leaks to

global)The untrusted code can only access objects returned by the enforcement sandbox

The implementation of policy is an

adaptation of Self-Protecting JavaScript

in ECMAScript 5 (solved the issues of Mozilla-specific features such as delete problem, getter, setter)

Page 14: A Two-Tier Sandbox Architecture for Untrusted JavaScript

14

The architecture in multiple-principal untrusted code

Policy 2Policy 1

untrusted

Policy 3

untrusted

untrusted

Base-line API implementation,in e.g. `api.js’ file

Page 15: A Two-Tier Sandbox Architecture for Untrusted JavaScript

15

Additional advantages

Policy definition is constrained by the outer-sandbox Even bad written policies can only

access the API, not the real DOM Whitelist (least-privilege)

implementation approach Only properties and objects defined in

policies are available to the untrusted code▪ Only define least-privilege policies to function

Page 16: A Two-Tier Sandbox Architecture for Untrusted JavaScript

16

Challenges & technical approach

Load and run remote JS code Server-side proxy + XMLHttpRequest

Base-line API implementation – complete mediation is essential Proxy API in Harmony ECMAScript

Dynamic loaded code, e.g. document.write(‘<script …>…</script>’), … Load and execute the script in the same

scope

Page 17: A Two-Tier Sandbox Architecture for Untrusted JavaScript

17

Validation

The prototype implementation is validated by a number of JS widgets and a context-sensitive web ad

On-going work In real applications, e.g., Google Maps,

Google Analytics, jQuery Ad networks – advertisement-specific

behaviors

Page 18: A Two-Tier Sandbox Architecture for Untrusted JavaScript

18

Summary and further work

The two-tier sandbox architecture separates API implementation and policy definition

Load and execute a piece of untrusted code in a sandboxed environment controlled by fine-grained, stateful policy enforcement

Further work will focus on practical issues to deploy the architecture to real-world scenarios

Page 19: A Two-Tier Sandbox Architecture for Untrusted JavaScript

19

Sponsors

The work is partial funded by the European FP7 project WebSand http://www.websand.eu

This talk, i.e. the trip, is supported the Ericsson Research Foundation

With the financial support from the Prevention of and Fight against Crime Programme of the European Union

Page 20: A Two-Tier Sandbox Architecture for Untrusted JavaScript

20

THANK YOU!

Page 21: A Two-Tier Sandbox Architecture for Untrusted JavaScript

21

Backup slides

Page 22: A Two-Tier Sandbox Architecture for Untrusted JavaScript

22

Mediation

alert implementation

JavaScript execution environment(e.g. browsers)Native implementations

code pointers User functions

alert(‘Hi!’) window.alert

alert wrapper(+policy code)

Attacker codealert = function(){...};

alert wrapper

unique

(enforced by SPJS)

Page 23: A Two-Tier Sandbox Architecture for Untrusted JavaScript

23

Base-line API and application-specific policiesvar node_map = WeakMap();function iHTMLDocument(){ node_map.set(this,document); }iHTMLDocument.prototype ={

getElementById : function(id){ try{ element = node_map.get(this).getElementById(id); return wrapNode(element); }catch(e){} },

//…}

var iDocument = new iHTMLDocument(); //base-linevar mydocument = enforceWhitelistPolicies(my_policy, iDocument);var api = {document: mydocument, …};

Application-specific policies

Page 24: A Two-Tier Sandbox Architecture for Untrusted JavaScript

24

A case studyM

en

u a

nd

oth

er

con

ten

ts:

no a

ccess

to

ad

scr

ipt

Allow restricted read access to the ad script

Allow restricted write access to the ad script

ad.js

Sandbox policy.j

s

api.js

Page 25: A Two-Tier Sandbox Architecture for Untrusted JavaScript

25

Deployment example

var api_and_enforcement = ...//baseline API & enforcement libary//using XMLHtmlRequest to get the content of file //`policy.js' into `policyCode' variablevar moduleMaker = cajaVM.compileModule(policyCode);var enforcedAPI = moduleMaker(api_and_enforcement);load_untrustedCode(enforcedAPI);function load_untrustedCode(api){ //using XMLHtmlRequest to get the content of file //`untrustedcode.js' into `untrustedCode' variable var moduleMaker = cajaVM.compileModule(untrustedCode); moduleMaker(api);}

See it?

Page 26: A Two-Tier Sandbox Architecture for Untrusted JavaScript

26

Wrappers

Wrap method callsbuiltin’ = builtinbuiltin = function(){ policy_check?

builtin’:null }

Property accesses__defineGetter__(…)__defineSetter__(…)

Built-in call

Built-in

Safewrapp

erPolicy

Page 27: A Two-Tier Sandbox Architecture for Untrusted JavaScript

27

Policy examples

Only allow URI in a white-list when sending by XMLHttpRequestwrap(XMLHttpRequest, whitelist_policy)

Do not allow send after cookie readdocument.__defineGetter__(‘cookie’,

cookie_policy) Limit the number of alerts to 2

wrap(window.alert, alert_policy)

Page 28: A Two-Tier Sandbox Architecture for Untrusted JavaScript

28

Deployment illustration<html> <head> <script src=“selfprotectingJS.js"></script> <title>Self-protecting JavaScript </title> <meta content=…> <style>…</style> <script>…</script> <!-- more heading setting --> </head> <body> <script type="text/javascript"> (function() {..})(); </script> <!-- the content of page --> </body></html>

Policy code and

enforcement code defined in a text file

The enforcement code can be

deployed anywhere: server side, proxy or browser plug-in, i.e.

no need for a modified browser

The orgininal

code is not syntactically modified

6.33

66.03

0

10

20

30

40

50

60

70

Self-Protecting BrowserShield

Slo

wd

ow

n (t

imes

)

Runtime overhead

Page 29: A Two-Tier Sandbox Architecture for Untrusted JavaScript

29

Tamper-proof issues

Wrapping library + policy code

... original.apply(this,args);...

Anonymous scope

Function• constructor• prototype • apply( )

• call( )

$virgin_apply = Function.prototype.apply;

inheritanceThis is a

general JavaScript problem

Page 30: A Two-Tier Sandbox Architecture for Untrusted JavaScript

30

Non-declarative argument issue

open implementation

JavaScript execution environment(e.g. browsers)Native implementations

code Policy checkerwindow.open("good.com","_blank","location=yes",true); Policy:

Only allow URL in awhitelist

var maliciousURL = {toString: function() { this.toString = function(){ return "bad.com"}; return "good.com"; }}window.open(maliciousURL);

good.com,..

good.com

Time of check

Time of use

bad.com

good.com,..

Page 31: A Two-Tier Sandbox Architecture for Untrusted JavaScript

31

WRAPPER

Declarative policies

CopyCombin

e

Policy

Built-in

x: {…}y:"_blank"z: "location=false" w:true

x: "string"y: *z: "string"w: "boolean"

x: "good.com"z: "location=false"w:true

x: "good.com"z: "location=true"w: false

x: "good.com"y:"_blank"z: "location=true"w:false

Copy values and coerce to the type specified by the policy

Policy can inspect and modify values

The output of the policy is

merged with the original input

x = {toString: function() { this.toString = function(){ return " bad.com"}; return "good.com";}}

Inspection type for policy

Page 32: A Two-Tier Sandbox Architecture for Untrusted JavaScript

32

Self-Protecting JavaScript revisited

Self-Protecting JavaScript Code TRUSTED

UNTRUSTED

Self-protecting JavaScript is appealing for untrusted dynamic loaded JavaScript does not parse or transform the code, and can enforce application-specific, modular

fine-grained policies at runtime However, due to the dangerous

features of current JavaScript, it is not possible to sandbox untrusted JavaScript without heavy restrictions, e.g. FacebookJS, ADsafe…

Page 33: A Two-Tier Sandbox Architecture for Untrusted JavaScript

33

ECMAScript 5 (ES5)

Patch dangerous features in current JavaScript

ES5 strict mode (ES5S) provides more restrictions

Credit: Taly at el, SP2011

Page 34: A Two-Tier Sandbox Architecture for Untrusted JavaScript

34

ES5 strict mode to SecureECMAScript

SecureECMAScript (SES) is a subset of ES5S, under consider to be included in future ECMAScript The Google Caja team developed SES as

an library In SES, untrusted JavaScript can be

loaded and executed dynamically in an isolated environment Without static validation, code filtering

or transformation

Page 35: A Two-Tier Sandbox Architecture for Untrusted JavaScript

35

Sandboxing untrusted code in SecureECMAScript 5 (Caja team)

Untrusted code executed in a sandbox can only interact with the outside world through a provided API var moduleMaker = cajaVM.compileModule(untrustedCodeSrc);var sandboxed = moduleMaker(api);

APIGlobal context

untrustedCode

sandbox

Page 36: A Two-Tier Sandbox Architecture for Untrusted JavaScript

36

Summary

Our approach is to control and modify the behaviour of JavaScript by wrapping the security-sensitive operations to make the code self-protecting no browser modifications non-invasive

▪ solve the problem of dynamic scripts▪ avoiding the need for extensive runtime code

transformation Can apply in sandboxing untrusted

JavaScript in ECMAScript 5