Self-Protecting JavaScript: A Lightweight Approach to Enforcing Security Policies
description
Transcript of Self-Protecting JavaScript: A Lightweight Approach to Enforcing Security Policies
Self-Protecting JavaScript: A Lightweight Approach to Enforcing Security Policies*
Phu H. PhungChalmers, Sweden
Stanford Security SeminarJuly 12, 2010
* This talk is based 2 joint papers with David Sands, Andrey Chudnov, Jonas Magazinius appeared on ASIACCS’09 & OWASP AppSec’10
The concern problems
• Injected (untrusted) JavaScript code (e.g.XSS) – A malicious user (the attacker) injects potentially
dangerous JavaScript code into a webpage via data entry in the webpage, e.g.:• blog• forum• web-mail
• Third party scripts (e.g. advertisement, mashup web applications)
• Buggy code
Difficult issues
• Parser mismatch problem: – filter does not always parse in the same way as
browser• Dynamic scripts problematic, e.g.
document.write, eval, ...<script> document.write(‘<scr’);document.write(‘ipt> malic’);var i= 1;document.write(‘ious code; </sc’);document.write(‘ript>’);</script>
<script> malicious code; </script>
The landscape of JavaScript security mechanisms
• Server filtering, but parser mismatch problem• Language subset, sandboxing• Behavioral sandboxing– Code transformation– No code transformation• Browser modification• No browser modification
Our approach: Use an Inlined Reference Monitor
• “inline” the policy into the JavaScript code so that the code becomes self-protecting
• The policy enforcement is implemented in a lightweight manner – does not require browser modification– non invasive: the original code (and any dynamically
generated code) is not syntactically modified– its implementation is a small and simple adaptation of an
aspect-oriented programming library
The policies
• The enforcement mechanism is security reference monitor-based• Ensure safety property of program execution
• Examples:• Only allow URI in a white-list when sending by
XMLHttpRequest• Do not allow send after cookie read• Limit the number of alerts to 2
Enforcement method
• Intercept JavaScript built-in method calls by inlining policy into the call– control or modify the bad behaviour
• Monitor access to sensitive properties
Enforcement method
alert implementation
JavaScript execution environment(e.g. browsers)Native implementations
code pointers User functions
alert(..) window.alert
alert wrapper(+policy code)
Attacker codealert = function(){...};
alert wrapper
unique
Phu H. Phung, David Sands, Andrey Chudnov – cse.chalmers.se
Dagstuhl 09141, 2 April 2009
Implementation
• Use aspect-oriented programming (AOP) style to intercept JavaScript API method calls var wrapper = function(object, method, Policy) {
//...
var original = object[method];
var aspect = function() {
//...
return Policy.apply(...,
proceed : function(){
return original.apply(...)
});
};
object[method] = aspect;
return aspect;
};
Monitoring Property access
• Use the setter and getter object.prototype.__defineGetter__(...),object.prototype.__defineSetter__(...)
• Property: even can redefine setter/getter, original wrapped properties are still protected
Deployment• Structure of a webpage containing policy
enforcement code
• Policies are located in the first script tag– Policy enforcement is applied for the rest of code
Dagstuhl 09141, 2 April 2009
The enforcement code can be deployed in any sides: server side,
proxy or plug-in
Secure the wrapper
• There are several issues that an attacker can exploit the wrapper– Function and Object Subversion• Modifying the Function/ Object –prototype
– Global setter subversion– Recover the wrapped built-in using aliases • Static aliases• Dynamic aliases
Function and Object Subversion
Object• prototype • valueOf( )
Function• constructor• prototype • apply( )
• call( )
{function instance}• constructor
Modifying subverts expected behavior
Wrapper:original.apply(this,args)
Attack code:var org;Function.prototype.apply =
function(){ org = this}
Fixing :original.apply= $virgin_apply
Global Setter subversion
Wrapper code
policy({args: arguments,
proceed: original})
Subversion
var org;Object.prototype.
__defineSetter__(‘proceed’, function(o) { org = o });
Fixing the wrapper:• No temporary objects?• Use “safe” objects…• Change JavaScript: Don’t execute setters upon instantiation (IE, Firefox)
Static aliases
alert
window.alert
Window.prototype.alert
constructor.prototype.alertwindow.__proto__.alert
window.window.alert
wrapper
Dynamic aliases
alert
alert alert
We provide pre-defined policies which enforce methods that possible return a window object with the same policies as the current window
Sane Policies
• Object and Function Subversion in Policies• Non Declarative Arguments
Function and Object Subversion in Policies
Policy code
var whitelist = {"good.com":true, "good2.org":true}
if(whitelist[address.substr(...))])
Fixing subversion• hasLocalProperty()• Use “safe” objects…
Subversion
Object.prototype[‘evil.com’]=true;*
String.prototype.substr = function(){ return ‘good.com’}
The policy writer should not have to remember this…
Credit: Meyerovich at el, WWW’10
“Safe” objects• safe() function– Creates a blank object which does not inherit from
the prototype-chain• {__proto__: null}
– Recursively copies all fields from the input object to the newly created copy
Non-declarative vs. declarative policies
Policy code
if (whitelist[address])img.src = address;
Fixing problem
Policy declare which types itexpects in a type language andmonitor enforces it
Attack
x = {toString: function() { this.toString=
function()’bad.com’;return ‘good.com’; }
}
Types for Declarative Argumentsargument array cloning by type:policy.toString(b) === ’xyz’
a b c
? ‘string’
? ‘xyz’
original argument array
inspection typeinspection argument array
Computation by policy code leading to call to invocation.proceed()
? ‘xy’ 42
policy’s modifiedargument array
Recombine with original argument
a ‘xy’ 42
and pass to original built-in
Example policy computation for some built-in called with (a,b,c). In this example the policy inspects b at type string and removes the last character, and sets the third parameter to 42 before calling proceed() in order to access the original built-in function. In the diagram ? is an abbreviation for undefined, and array objects are depicted as boxes.
policy function proceed function
Summary
• Our approach is to control and modify the behaviour of JavaScript by transforming the code to make it self-protecting– no browser modifications– non-invasive
• solve the problem of dynamic scripts• avoiding the need for extensive runtime code transformation
• Possible vulnerabilities of the library are addressed and fixed
• Typing for arguments to prevent
Dagstuhl 09141, 2 April 2009
References
• Jonas Magazinius, Phu H. Phung, and David Sands (2010). Safe Wrappers and Sane Policies for Self Protecting JavaScript. OWASP AppSec Research 2010, June 2010.
• Phu H. Phung, David Sands, and Andrey Chudnov (2009). Lightweight Self-Protecting Javascript (ASIACCS 2009)
The papers are available at:http://www.cse.chalmers.se/~phung/projects/jss
Further work
• Case studies for particular web applications• Fully develop the framework, including
treating mashups, policies that span multiple pages
• Authoring policies:– Not easy for the programmer to ensure that all
objects are safe • Strong motivation for defining a policy language for
authoring policies which are well behaved.
Thank you!