Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Virtual Values for Taint and Information Flow Analysis, Thomas H. Austin

Meta Workshop
October 30, 2016

Virtual Values for Taint and Information Flow Analysis, Thomas H. Austin

Meta Workshop

October 30, 2016
Tweet

More Decks by Meta Workshop

Other Decks in Research

Transcript

  1. Virtual Values for Taint and Information Flow Analysis Prakasam Kannan

    Thomas H. Austin Mark Stamp Tim Disney Cormac Flanagan
  2. Securing JavaScript • The primary client-side language • Popular server-side language – Node.js,

    Nashorn, IronJS, Rhino • Goal: systemic defense against data leaks/data corruption
  3. Good news, everyone! We can secure web applications with information

    flow analysis. We'll need to make extensive changes to the web browser… … and there will be some performance overhead...
  4. How can we best integrate our controls? •  Can't slow

    down JS engines •  Don't break the web – let developers opt in? • Support different JavaScript engines
  5. JavaScript proxies (Van Cutsem & Miller 2010) • Intercession API • Part

    of ECMAScript 6 • Behavior of proxy object determined by handler – handler: specifies traps that define the proxy's behavior
  6. Proxy traps (partial list) •  get(targ, prop, rcvr) •  set(targ,

    prop, val, rcvr) •  has(targ, prop) •  deleteProperty(targ, prop) •  apply(targ, self, args) •  construct(targ, args, newTarg) Overrides behavior for operations on objects & functions
  7. Proxy example: tracing API function trace(o) { return new Proxy(o,

    { get: function(targ, prop) { console.log("Getting " + prop); return targ[prop]; }, set: function(targ, prop, newVal) { console.log("Setting " + prop + " to " + newVal); targ[prop] = newVal; return true; } }); }
  8. var o = trace({}); o.hello = "world"; var s =

    "Goodbye cruel " + o.hello; Output: Setting hello to world Getting hello
  9. But… primitive values var i = trace(42); var x =

    i++; TypeError: Cannot create proxy with a non-object as target or handler
  10. Virtual Values (Austin et al., OOPSLA 2011) •  Extends proxies

    for primitive values •  Additional hooks for values: – unary(target, op, operand) – left(target, op, right) – right(target, op, left) – test(cond, branchExit) – assign(left, right, asgnThunk)
  11. Virtual Values (Austin et al., OOPSLA 2011) •  Extends proxies

    for primitive values •  Additional hooks for values: – unary(target, op, operand) – left(target, op, right) – right(target, op, left) – test(cond, branchExit) – assign(left, right, asgnThunk) New traps needed for information flow
  12. Strategy • Use Sweet.js (v. 0.7.8) macros to rewrite code – hygienic

    – supports rewriting of operators • Revised code includes hooks for virtual values
  13. Helper functions •  Proxy(value, handler, key) – wraps JS Proxy function

    – key lets proxies recognize themselves •  unproxy(value, key) – returns handler for value – unproxyMap stores handlers •  isVProxy(value) – tests whether value is a virtual value
  14. harness code: binary function function binary(operator, left, right) { if

    (isVProxy(left)) { var t = unproxyMap.get(left).target; return unproxyMap.get(left).handler .left(t, operator, right); } else if (isVProxy(right)) { var t = unproxyMap.get(right).target; return unproxyMap.get(right).handler .right(t, operator, left); } else if (operator === "*") { return left * right; } // Other operators elided… } Unary operators handled similarly
  15. Taint analysis •  Taint analysis focuses on integrity: – does "dirty"

    data corrupt trusted data? •  Integrated into Perl and Ruby •  Handles explicit flows only – direct assignment – passing parameters
  16. Taint analysis API • taint(value) – marks a value as "dirty" • isTainted(value)

    • endorse(taintedVal) – removes the taint from a value
  17. Taint analysis example var username = taint( "Robert'); DROP TABLE

    Students;--"); var query = "select * from Students " + "where username = '" + username + "'"); if (isTainted (query)) throw new Error("Tainted query");
  18. taint function function taint(originalValue) { if (isTainted(originalValue)) return originalValue; var

    p = new Proxy(originalValue, taintingHandler, taintingKey); return p; }
  19. taint function function taint(originalValue) { if (isTainted(originalValue)) return originalValue; var

    p = new Proxy(originalValue, taintingHandler, taintingKey); return p; } Used to identify tainted values.
  20. Handler for tainting { originalValue: originalValue, unary: function (target, op,

    operand) { return taint(unaryOps[op](target)); }, left: function (target, op, right) { return taint(binaryOps[op](target,right)); }, right: function (target, op, left) { return taint(binaryOps[op](left, target)); } }
  21. Handler for tainting { originalValue: originalValue, unary: function (target, op,

    operand) { return taint(unaryOps[op](target)); }, left: function (target, op, right) { return taint(binaryOps[op](target,right)); }, right: function (target, op, left) { return taint(binaryOps[op](left, target)); } } Array of functions performing unary operations Array of functions performing binary operations
  22. endorse function function endorse (value) { if (isTainted(value)) { var

    hndl = unproxy(value, taintingKey); return hndl.originalValue; } return value; }
  23. Information Flow Analysis •  Related to taint analysis •  Focuses

    on confidentiality: – does secret data leak to public channels? •  Assumes attacker controls some code •  Must consider implicit flows – can the attacker deduce secrets?
  24. Implicit flow var x = secret(true); var y = false;

    if (x) y = true; console.log("x = " + y); Implicit flow from x to y
  25. Additional hooks used for information flow •  unary(target, op, operand)

    •  left(target, op, right) •  right(target, op, left) •  test(cond, branchExit) •  assign(left, right, assignThunk)
  26. harness code: test function function test(cond, branchExit){ if (isVProxy(cond)){ return

    unproxyMap.get(cond) .handler.test(cond, branchExit); } return cond; }
  27. Sweet.js macro for if statements macro if { rule {($cond

    ...) { $body ...}} => { function exit() {} // default no-op if (vvalues.test($cond..., cb => exit = cb)){ $body ... exit(); } } }
  28. harness code: assign function function assign(left, right, assignThunk) { if

    (isVProxy(left)) { return unproxyMap.get(left).handler .assign(left, right, assignThunk); } else if (isVProxy(right)) { return unproxyMap.get(right).handler .assign(left, right, assignThunk); } else { return assignThunk (); } }
  29. Information Flow analysis API •  Similar to taint analysis – unary

    / left / right traps – secret / isSecret functions •  test trap tracks implicit flows •  assign trap crashes on unsafe updates – no-sensitive-upgrade strategy – Zdancewic 2002
  30. test trap tracks implicit flows test: function(cond, branchExit) { if

    (cond) { pcStack.push(cond); branchExit(() => { pcStack.pop(); }) } return cond; }
  31. test trap tracks implicit flows test: function(cond, branchExit) { if

    (cond) { pcStack.push(cond); branchExit(() => { pcStack.pop(); }) } return cond; } Array of conditions marked by secret
  32. assign trap crashes to stop implicit flows assign: function(left, right,

    assignThunk) { if (!isSecret(left) && pcStack.length > 0) { throw new Error("Implicit leak"); } assignThunk(); } and execution depends on secret data … If the lhs is a public variable … then crash the program.
  33. Overhead of Virtual Values Base Virtual Values Slowdown Safari 83.1

    ms 588.1 ms 7.1x Chrome 130.4 ms 544.3 ms 4.2x Firefox 142.3 ms 751.6 ms 5.3x •  SunSpider benchmark suite, v 1.02 •  no-op virtual values
  34. Final thoughts •  Virtual values + Sweet.js can introduce advanced

    security controls •  Future plans – More use cases for test and assign? – integrate with new version of Sweet.js – more advanced controls