1 / 49

Dependent Types for JavaScript

Dependent Types for JavaScript. Ravi Chugh Ranjit Jhala. University of California, San Diego. David Herman. Mozilla Research. Dependent Types for JavaScript. A Large Subset of. Goal: Precise and Flexible Reasoning for Fine-Grained Security. But hard even for simple type invariants!.

shaman
Download Presentation

Dependent Types for JavaScript

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DependentTypes for JavaScript Ravi ChughRanjitJhala University of California, San Diego David Herman Mozilla Research

  2. DependentTypes for JavaScript A Large Subset of Goal:Precise and Flexible Reasoningfor Fine-Grained Security But hard even for simple type invariants!

  3. Outline • Challenges • Tour of DJS • Security Predicates

  4. Challenges: Unions and Mutation varreadLinks= function (doc, max) { if (!max) max = 10 if (doc.domain() == “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } readLinks(document,5) // read at most 5 links … readLinks(document) // … or 10 by default integer or undefined…

  5. Challenges: Unions and Mutation varreadLinks= function (doc, max) { if (!max) max = 10 if (doc.domain() == “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } readLinks(document,5) readLinks(document) integer or undefined…

  6. Challenges: Unions and Mutation varreadLinks= function (doc, max) { if (!max) max =10 if (doc.domain() == “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } readLinks(document,5) readLinks(document) integer or undefined… … but now definitely an integer

  7. Challenge: Objects varreadLinks= function (doc, max) { if (!max) max =10 if (doc.domain()== “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } readLinks(document,5) readLinks(document) prototype inheritance, mutability, dynamic keys

  8. Challenge: Arrays varreadLinks= function (doc, max) { if (!max) max =10 if (doc.domain()== “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } readLinks(document,5) readLinks(document) • “length”, “holes”, • non-integer keys, prototypes

  9. DependentJavaScript[OOPSLA ’12] • System D[POPL ’12] “Usability” refinement types F≤ ∨, ∧ + nested refinements DJS occurrence types … Coq dependent types syntactic types JS Expressivity

  10. Outline • Challenges • Tour of DJS • Security Predicates

  11. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes

  12. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Refinement Types {x|p} Bool Num  Int Top  {b|tag(b)=“boolean”} {n|tag(n)=“number”} {i|tag(i)=“number”integer(i)} {x|true} “value x such that formula p is true”

  13. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Refinement Types {x|p} {x|p} 3 :: 3 :: 3 :: 3 :: {i|i>0} Int Num {i|i=3} “value x such that formula p is true” “value x such that formula p is true”

  14. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Subtyping is Implication* {i|i=3}<:{i|i>0}<:Int <:Num i=3 i>0 tag(i)=“number”integer(i) tag(i)=“number”

  15. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Nested Refinements • McCarthy’s decidable theory of arrays {d|Bool(sel(d,“f”))∧ sel(d,k)::IntInt} • uninterpreted System D “has-type” predicatenests typing relation inside formulas

  16. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Nested Refinements SyntacticSubtyping + Subtyping is Implication* UninterpretedValidty Implication* =

  17. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Path and Flow Sensitivity varreadLinks= function (doc, max) { if (!max) { max =10 } else{ } … /*: readLinks :: (Ref(~doc), Int?)Top */ max0:Int? max1:{v|v=10} (max0≠undefined) max2:{v|v=max0} max12:Int T?{x|T(x)x=undefined}

  18. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Path and Flow Sensitivity varreadLinks= function (doc, max) { if (!max) { max =10 } else{ } … /*: readLinks :: (Ref(~doc), Int?)Top */ max0:Int? max12:Int T?{x|T(x)x=undefined}

  19. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Path and Flow Sensitivity x1:{v|v=upd(x0,k,7)} x0:Empty varx = { } x[k]=7 Strong updates to singleton objects Weak updates to collections of objects

  20. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Track types, “packedness,” and lengthof arrays where possible {a|a::Arr(A) {a|packed(a) {a|len(a)=10} • … • … • … • A? • -1 • 0 • A? • A? • 1 • 2 • A? • A? • len(a) • A? A?{x|A(x)x=undefined} X{x|x=undefined} • … • … • … • X • A • A • A • A • X

  21. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes • x:T1/H1T2/H2 • (Quick Detour) • Function types includelocal heap pre- and post-conditionsà la separation logic input type output heap input heap output type

  22. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes extern getIdx :: All A. (a:Ref, i:Int) / (a0:Arr(A))  {a1| (a1 :: A ∨ a1 = undefined)∧ 1(packed(a0)  ite (0 <= i < len(a0)) 11 (a1 :: A)) 11(a1 = undefined)} / same input type / heap ite p q1 q2 (pq1) ∧ (pq2) (a1:{v|v=a0}) output type / heap

  23. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes extern setIdx :: All A. (a:Ref, i:Int, y:A) / (a0:Arr(A))  Top / (a1:{a1:: Arr(A) ∧ 1(packed(a0) ∧0 <= i < len(a0)  packed(a1) ∧len(a1) = len(a0)) ∧ 1 (packed(a0) ∧i = len(a0)  packed(a1) ∧len(a1) = len(a0) + 1)})

  24. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes extern __ArrayProto :: {v|sel(v,“pop”)::… ∧ sel(v,“push”)::… ∧ …}

  25. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes varreadLinks= function (doc, max) { if (!max) max =10 if (doc.domain()== “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } maxinv:Int iinv:{v|v>=0} eltsinv:{a|a=elts0} Elt.protoinv:{d|…} Heap invariants before and after each iteration Type checker infers heap for common cases

  26. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes DJS handles prototypes…

  27. 13 benchmarksmainly from SunSpider and JSGP • 300 unannotated LOC • 35% annotation overhead • 11 benchmarks run in <1s • 2 benchmarks run in 2-6s DJSProgram DesugarerBased on Guha et al.[ECOOP ’10] Z3 SMTSolver Type Checker Desugared Program

  28. Outline • Challenges • Tour of DJS • Security Predicates

  29. Browser Extension Security • Can we track fine-grained policies directly in JS? “Degree of JavaScript” ? ADsafetyPolitz et al.[SEC ’11] DJS JS IBEX • Guha et al.[SP ’11] ML Granularityof Invariants fine coarse

  30. /*: readLinks :: (Ref(~doc), Int?)Top */ varreadLinks= function (doc, max) { if (!max) max =10 if (doc.domain()== “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } • Allow extension to read this attribute?

  31. /*: assume forall (e d) (eltTagName e “a” ∧ eltInDoc e d ∧ docDomain d “newyorker.com”)  canReadAttr e “href”*/ • IBEX-style security policy /*: readLinks :: (Ref(~doc), Int?)Top */ varreadLinks= function (doc, max) { if (!max) max =10 if (doc.domain()== “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } • Type check against IBEX-style DOM API

  32. extern Elt.prototype.getAttr :: (this:Ref(~elt), k:Str)  Str

  33. extern Elt.prototype.getAttr :: (this:Ref(~elt),{k|Str(k)∧canReadAttr this k})  {s|Str(s)∧attrOfElt this k s}

  34. extern Elt.prototype.getAttr :: (this:Ref(~elt),{k|Str(k)∧canReadAttr this k)  {s|Str(s)∧attrOfElt this k s} extern Doc.prototype.domain :: (this:Ref(~doc))  Str

  35. extern Elt.prototype.getAttr :: (this:Ref(~elt),{k|Str(k)∧canReadAttr this k)  {s|Str(s)∧attrOfElt this k s} extern Doc.prototype.domain :: (this:Ref(~doc))  {s|Str(s)∧docDomain this s}

  36. extern Elt.prototype.getAttr :: (this:Ref(~elt),{k|Str(k)∧canReadAttr this k)  {s|Str(s)∧attrOfElt this k s} extern Doc.prototype.domain :: (this:Ref(~doc))  {s|Str(s)∧docDomain this s} extern Doc.prototype.getEltsByTagName :: …

  37. /*: assume forall (e d) (eltTagName e “a” ∧ eltInDoc e d ∧ docDomain d “newyorker.com”)  canReadAttr e “href”*/ • IBEX-style security policy /*: readLinks :: (Ref(~doc), Int?)Top */ varreadLinks= function (doc, max) { if (!max) max =10 if (doc.domain()== “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) for (var i = 0; i < elts.length && i <= max; i++) { elts[i].getAttr(“href”) } } } ✓ • Type check against IBEX-style DOM API

  38. Current Status 9 of 17 IBEX examples ported to DJS Total running time ~3s Invariants translate directly (so far)

  39. Conclusion DJS able to tracksimple type invariants, and security predicatesseem within reach

  40. Thanks! D ravichugh.com/djs :: • github.com/ravichugh/djs

  41. Extra Slides

  42. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes vargrandpa= …, parent = Object.create(grandpa), child = Object.create(parent), b= kin child, • Key Membership via Prototype Chain Unrolling b :: {v|v=trueiff (has(child,k) (has(parent,k) (has(grandpa,k) (HeapHas(H,great,k))} child parent great H (Rest of Heap) grandpa

  43. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes vargrandpa= …, parent = Object.create(grandpa), child = Object.create(parent), b= kin child, x= child[k] • Key Lookup viaPrototype Chain Unrolling x :: {v|ifhas(child,k) then v=sel(child,k) {v|elifhas(parent,k) then v=sel(parent,k) {v|elifhas(grandpa,k) then v=sel(grandpa,k) {v|elifHeapHas(H,great,k)) then v=HeapSel(H,great,k)) {v|elsev=undefined}

  44. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Key Idea Reduce prototype semantics to decidable theory of arrays via flow-sensitivity and unrolling

  45. Refinements • Path and Flow Sensitivity • Arrays • Loops • Prototypes Encode tuplesas arrays vartup= [5, “guten abend!”] {a|a::Arr(Top) {a|packed(a)len(a)=2 {a|Int(a[0]) {a|Str(a[1])}

  46. varreadLinks= function (doc, max) { if (!max) max = 10 if (doc.domain() == “newyorker.com”) { var elts = doc.getEltsByTagName(“a”) var i = 0 var loop = function loop () { if (i < elts.length && i <= max) { elts[i].getAttr(“href”) i++ loop() } else { undefined } } loop() } } Desugared Loop max:-Int i :-{v|v>=0} elts:-{a|a=elts0} Elt.proto:-{d|…}

  47. {p}{v|p} /*: x:NumOrBool {iteNum(x) Num(v) Bool(v)} */ function negate(x) { x=(typeofx==“number”)? 0 – x : !x returnx } /*: x:Any{vifffalsy(x)} */ function negate(x) { x=(typeofx==“number”)? 0 – x : !x returnx }

  48. Function Types and Objects • x:T1/H1T2/H2 input type output heap input heap output type ObjHas(d,k,H,d’)has(d,k)HeapHas(H,d’,k) /*: x:Ref / [x |-> d:Dict |> ^x] {viffObjHas(d,”f”,curHeap,^x)} / sameHeap */ function hasF(x) { return“f”in x }

  49. Function Types and Objects • x:T1/H1T2/H2 input type output heap input heap output type ObjSel(d,k,H,d’) itehas(d,k) sel(d,k) HeapSel(H,d’,k) /*: x:Ref / [x |-> d:Dict |> ^x] {v=ObjSel(d,”f”,curHeap,^x)} / sameHeap */ function readF(x) { returnx.f }

More Related