Modern Type Systems for Dynamic Languages Ravi Chugh Web Platform 2 Goal: Rigorous Foundations Web Platform 3 1995 <html> Web Page = Static HTML Web Page + Links Web Page + Client-Side Code <script type=“javascript”> Username Password Login </html> loginButton.onclick = function () { if (passwordBox.value == “”) { alert(“Enter password!”); } else { ... }} </script> 4 1995 No Static Types “Dynamic” Features Make it Easy to Experiment… … an easy-to-use “scripting language” as a companion to Java Brendan Eich, JavaScript creator 5 2014 2014 Asked whether Gmail would ever open up an API for developers to code add-ons and plug-ins with more official support and stability, Kowitz suggested it was unlikely. Gmail is based on “hundreds of thousands” of lines of JavaScript, Kowitz said, and it's a code base that “changes so quickly.” That said, Jackson said the Gmail team "loves" to see third-party functionality being developed, and the team tries to make developers aware of changes they know will affect those products. Article on LifeHacker 2014 Asked whether Gmail would ever open up an API for developers to code add-ons and plug-ins with more official support and stability, Kowitz suggested it was unlikely. Gmail is based on “hundreds of thousands” of lines of JavaScript, Kowitz said, and it's a code base that “changes so quickly.” That said, Jackson said the Gmail team "loves" to see third-party functionality being developed, and the team tries to make developers aware of changes they know will affect those products. “Scripting” ?!? Article on LifeHacker 2014 Count Tag 599,605 C# 583,322 Java JavaScript is Pervasive 555,164 JavaScript 532,851 PHP 273,086 Python 268,725 C++ 129,483 C 97,154 Ruby 15,044 Haskell 2,175 OCaml http://stackoverflow.com/tags 02-26-14 9 2014 Count Tag 599,605 C# 583,322 Java JavaScript is Pervasive 555,164 JavaScript 532,851 PHP 273,086 Python 268,725 C++ Other Dynamic Languages Are, Too 129,483 C 97,154 Ruby 15,044 Haskell 2,175 OCaml http://stackoverflow.com/tags 02-26-14 10 2014 Banking Shopping News JavaScript is Pervasive 11 2014 Banking Shopping News JavaScript is Pervasive 12 2014 Banking Shopping News JavaScript is Pervasive 13 2014 Third-Party JavaScript is Pervasive 14 2014 No longer just “scripting” … an easy-to-use “scripting language” as a companion to Java 15 Significant Interest For: 1. Development Tools 2. Reliability / Security 3. Performance But JS is hard to reason about! 16 My Ph.D. Static Types for Dynamic Languages JavaScript, Python, Ruby, PHP Share Common Challenges New Techniques Apply Broadly, Even to Statically Typed Languages 17 Static Types Describe sets of run-time values “booleans” “integers” “non-null pointers” “objects with foo field” “urls that are safe to visit” 18 Static Types Prevent classes of run-time errors “booleans” “multiply int and bool” “integers” “null pointer “non-null exception” pointers” “foo field field “foo “objects with not found” not foofound” field” “navigating “redirect toto “urls that are evil.com” safe to visit” 19 f(x) “actual args” Type1 “expected args” Type2 “function call produces no error” 20 f(x) “actual args” Type1 “expected args” Type2 “function call may produce error” 21 For all programs p in PROGRAMS If p has a type T in TYPES Then p does not fail with any error e in ERRORS 22 GOAL: Reason About More Programs For all programs p in PROGRAMS If p has a type T in TYPES Then p does not fail with any error e in ERRORS 23 GOAL: Reason About More Programs For all programs p in PROGRAMS If p has a type T in TYPES Then p does not fail with any error e in ERRORS GOAL: Eliminate More Errors 24 TYPES 25 Refinement Types Types + Logic TYPES 26 Refinement Types Types + Logic “actual args” “expected args” { xType | p1 } { Type x|q} {x|p} {x|q} 2 27 Refinement Types Types Logic {x|p} f :: { y | q } Nested Refinements [POPL ’12] Key to Encode Dynamic Features 28 Usability Types + Logic Dependent JavaScript (DJS) [POPL ’12, OOPSLA ’12] Verification Hoare Logics Model Checking Abstract Interpretation Theorem Proving … Expressiveness Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Important? Why is JavaScript Hard? PROGRAMS TYPES Static Types via Logic Security via Logic ERRORS Looking Ahead 30 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Important? Why is JavaScript Hard? PROGRAMS TYPES Static Types via Logic Security via Logic ERRORS Looking Ahead 31 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Hard? PROGRAMS Lightweight Reflection Dictionary Objects Additional Challenges 32 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead function negate(x) { if (typeof x == “number”) { Q: What is my “type”? x } 33 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead All JavaScript Values { x | tag(x) = “number” } 3.14 -1 17 42 ... Q: What is my “type”? x { x | tag(x) = “object” } { x | tag(x) = “boolean” } true {} { “f”:17 } ... { “f”:42, “g”:true } false 34 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead function negate(x) { if (typeof x == “number”) { Q: What is my “type”? A: Described by “tag” x } 35 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead function negate(x) { if (typeof x == “number”) { return 0 - x; } else { return !x; } } “expected args” values with tag “number” OR “boolean” 36 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Hard? PROGRAMS Lightweight Reflection Dictionary Objects Additional Challenges 37 Why JavaScript? Challenges obj.f Types via Logic means Security via Logic Looking Ahead obj[“f”] Objects are “Dictionaries” a.k.a. that map “maps” string keys “hash tables” “associative to values arrays” 38 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead function dispatch(table, op, i, j) { } method table method to invoke 39 Why JavaScript? Challenges Types via Logic function dispatch(table, op, i, j) { var fn = table[op]; return fn(i, j); } var integerOps = { “+” : function (n, m) { … } , “-” : function (n, m) { … } }; Security via Logic Looking Ahead “foo field “*” key not found” found dispatch (integerOps, “*”, 17, 42); 40 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead function dispatch(table, op, i, j) { var fn = table[op]; return fn(i, j); } “expected args” Dependency between types of arguments table object with an op key that stores a function on numbers 41 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Hard? PROGRAMS Lightweight Reflection Dictionary Objects Additional Challenges 42 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Hard? PROGRAMS Lightweight Reflection Dictionary Objects Extensible Objects Prototype Inheritance JavaScript Peculiarities 43 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Hard? Unsupported in Prior Work PROGRAMS Lightweight Reflection Dictionary Objects Extensible Objects Prototype Inheritance JavaScript Peculiarities 44 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Important? Why is JavaScript Hard? PROGRAMS TYPES Static Types via Logic Security via Logic ERRORS Looking Ahead 45 Why JavaScript? Challenges Types via Logic Security via Logic All JavaScript Values { x | tag(x) = “number” } 3.14 -1 17 true Looking Ahead 42 ... {} { “f”:17 } ... { “f”:42, “g”:true } false 46 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead All JavaScript Values { x | tag(x) = “number” } 3.14 -1 17 42 ... { x | tag(x) = “object” } { x | tag(x) = “boolean” } true {} { “f”:17 } ... { “f”:42, “g”:true } false 47 Why JavaScript? Challenges Types via Logic Security via Logic All JavaScript Values { x | integer(x) } {x|x>0} -1 17 true Looking Ahead 42 3.14 ... {} { “f”:17 } ... { “f”:42, “g”:true } false 48 Why JavaScript? Challenges Types via Logic Refinement Types Security via Logic Looking Ahead All JavaScript Values {x|p} “set of values x s.t. formula p is true” 49 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead f(x) “actual args” Type1 “expected args” Type2 50 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead f(x) “actual args” “expected args” {x|p} {x|q} {x|p} {x|q} 51 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Subtyping is Implication Source of Expressive Power { xType |p} { Type x|q} {x|p} {x|q} 1 2 52 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Static Types via Logic TYPES Lightweight Reflection Dictionary Objects Key Technical Innovations Evaluation 53 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead //: negate :: (x:NumOrBool) NumOrBool function negate(x) { if (typeof x == “number”) { Type Annotation in Comments return 0 - x; } else { Syntactic Sugar return !x; }} NumOrBool for Common Types { v | tag(v) = “number” tag(v) = “boolean” } 54 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead //: negate :: (x:NumOrBool) NumOrBool function negate(x) { if (typeof x == “number”) { return 0 - x; } else { return !x; “expected args” }} { x | tag(x) = “number” } { x | tag(x) = “number” } { x | tag(x) = “number” } { x | tag(x) = “number” } 55 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead //: negate :: (x:NumOrBool) NumOrBool function negate(x) { if (typeof x == “number”) { return 0 - x; } else { return !x; }} { x | not(tag(x) = “number”) { x | ∧ (tag(x) = “number” ∨ {x| “expected args” { x | tag(x) = “boolean” } tag(x) = “boolean”) } 56 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead //: negate :: (x:NumOrBool) NumOrBool function negate(x) { if (typeof x == “number”) { return 0 - x; } else { return !x; }} Logic Enables Path-Sensitive Reasoning on Branches 57 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead //: negate :: (x:NumOrBool) { y|tag(y) = tag(x) } function negate(x) { if (typeof x == “number”) { return 0 - x; } else { return !x; }} Logic Enables Types to Depend on Values 58 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Static Types via Logic TYPES Lightweight Reflection Dictionary Objects Key Technical Innovations Evaluation 59 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead All JavaScript Values { x | tag(x) = “object” } {} { “f”:17 } { “f”:true } { “f”:42, “g”:null } ... 60 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead All JavaScript Values {} { x | tag(x) = “object” has(x,“f”) } { “f”:17 } { “f”:true } { “f”:42, “g”:null } ... 61 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead All JavaScript Values {} { x | tag(x) = “object” { x | has(x,“f”) { x | tag(sel(x,“f”)) = “number” } { “f”:17 } { “f”:true } { “f”:42, “g”:null } ... 62 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead //: dispatch :: //: ({ table | tag(table) = “object” }, //: { op | tag(op) = “string” //: { op | ∧ has(table,op) //: { op | ∧ sel(table,op) :: (Num,Num) Num }, //: { i | tag(i) = “number” }, //: { j | tag(j) = “number” }) //: Num function dispatch(table, op, i, j) { var fn = table[op]; return fn(i, j); } 63 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead //: dispatch :: //: (table : { sel(table,op) :: (Num,Num) Num }, //: op : Str, //: i : Num, //: j : Num) //: //: //: Num function dispatch(table, op, i, j) { var fn = table[op]; return fn(i, j); } 64 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead var integerOps = { “+” : …, “-” : … }; dispatch (integerOps, “*”, 17, 42); “actual args” { op | op = “*” } { op | op = “*” } { op | has(integerOps,op) } { op | has(integerOps,op) } Type Checking Prevents Run-Time Error 65 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Static Types via Logic Lightweight Reflection Dictionary Objects Key Technical Innovations Evaluation 66 Why JavaScript? Challenges Types via Logic Prior Refinement Types Security via Logic Looking Ahead Dependent JavaScript (DJS) [POPL ’12, OOPSLA ’12] lightweight reflection dictionary objects extensible objects prototype inheritance JavaScript peculiarities 67 Why JavaScript? Challenges Types via Logic Prior Refinement Types Security via Logic Looking Ahead Dependent JavaScript (DJS) [POPL ’12, OOPSLA ’12] dictionary objects Key Challenge: Function Subtyping as Logical Implication 68 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead 42 + negate (17) { f | f :: { f | f :: } (x:NumOrBool) { y|tag(y) = tag(x) } } (x:Num) Num “expected function” 69 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead How to Prove { f | f :: { f | f :: } (x:NumOrBool) { y|tag(y) = tag(x) } } (x:Num) Num ? How to Encode Type System Inside Logic? Prior Refinement Systems Disallow Function Types Inside Logic! 70 Why JavaScript? Challenges Types via Logic Types Security via Logic Looking Ahead Refinement Logic T ::= { x | p } | T1 T2 [Prior State-of-the-Art] Satisfiability Modulo Theories (SMT) SAT + Decidable Theories pq SMT Solver (e.g. Z3) 71 Why JavaScript? Types T ::= { x | p } | T1 T2 Challenges Types via Logic Security via Logic Looking Ahead Refinement Logic p ::= p ∧ q | p ∨ q | p | x=y|x>y|… | tag(x) = “number” | … | sel(x,k) = 17 | … • Boolean Connectives • Equality • Linear Arithmetic • Uninterpreted Functions • McCarthy Arrays 72 Why JavaScript? Types T ::= { x | p } | T1 T2 Challenges Types via Logic Security via Logic Looking Ahead Refinement Logic p ::= p ∧ q | p ∨ q | p | x=y|x>y|… | tag(x) = “number” | … | sel(x,k) = 17 | … Enables Union Types and Lightweight Reflection NumOrBool { v | tag(v) = “number” tag(v) = “boolean” } 73 Why JavaScript? Challenges Types T ::= { x | p } | T1 T2 Types via Logic Security via Logic Looking Ahead Refinement Logic p ::= p ∧ q | p ∨ q | p | x=y|x>y|… | tag(x) = “number” | … | sel(x,k) = 17 | … Enables Dictionary Types with Dynamic Keys … But Disallows Functions in Dictionaries! { d | tag(sel(d,k)) = “boolean” ∧ { d | tag(sel(d,“f”)) = “function” ∧ { d | sel(d,“f”) ??? } 74 Why JavaScript? Challenges Types T ::= { x | p } | T1 T2 Types via Logic Security via Logic Looking Ahead Refinement Logic p ::= p ∧ q | p ∨ q | p | x=y|x>y|… | tag(x) = “number” | … | sel(x,k) = 17 | … | sel(x,k) :: T1 T2 | … Goal: Refer to Type System Inside Logic Goal: Without Giving up Decidability Solution: Nested Refinements! 75 Why JavaScript? Types T ::= { x | p } Challenges Types via Logic Security via Logic Looking Ahead Refinement Logic p ::= p ∧ q | p ∨ q | p | x=y|x>y|… | tag(x) = “number” | … | sel(x,k) = 17 | … | sel(x,k) :: T1 T2 | … Nested Refinements [POPL ’12] 1. Decidable Encoding 2. Precise Subtyping 3. Type Soundness Proof 76 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Decidable Encoding { f | f :: { f | f :: } (x:NumOrBool) { y|tag(y) = tag(x) } } (x:Num) Num Uninterpreted Predicate in Logic Distinct Uninterpreted Constants in Logic… 77 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Decidable Encoding { f | f :: { f | f :: } (x:NumOrBool) { y|tag(y) = tag(x) } } (x:Num) Num Uninterpreted Predicate in Logic Distinct Uninterpreted Constants in Logic… w/ Types Nested Inside 78 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Decidable Encoding { f | f :: { f | f :: SMT Solver } (x:NumOrBool) { y|tag(y) = tag(x) } } (x:Num) Num Trivially Decidable, but Imprecise 79 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Precise Subtyping {f|p} { f | f :: (x:S1) S2 Step 1: Find p f :: Step 2: Compare such that SMT Solver (x:S1) S2 (x:S1) S2 “contra-variance” “co-variance” } (x:T1) T2 x:T1 and (x:T1) T2 T1 S1 S2 T2 80 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Precise Subtyping { f | f = negate } { f | f :: } (x:Num) Num Step 1: f = negate SMT f :: Solver (x:NumOrBool) { y|tag(y) = tag(x) } Step 2: 81 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Precise Subtyping { f | f = negate } { f | f :: } (x:Num) Num Step 1: f = negate SMT f :: Solver (x:NumOrBool) { y|tag(y) = tag(x) } Step 2: x:Num Num { y | tag(y) = tag(x) } NumOrBool Num 82 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Precise Subtyping { f | f = negate } Step 1: { f | f :: } (x:Num) Num Decidable Reasoning via SMT + Step 2: Precise Function Subtyping via Syntactic Techniques 83 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Type Soundness Proof Conventional Proofs Require Logic to be an Oracle … Type System 0 Logic 0 … but Nesting Introduces Circularity That Prevents Typical Inductive Proofs 84 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Type Soundness Proof Proof Technique: Stratify into Infinite Hierarchy Type System ∞ Type System 0 Logic 0 Type System 1 Logic 1 Type System 2 Logic 2 … … 85 Why JavaScript? Challenges Types T ::= { x | p } Types via Logic Security via Logic Looking Ahead Refinement Logic p ::= p ∧ q | p ∨ q | p | x=y|x>y|… | tag(x) = “number” | … | sel(x,k) = 17 | … | sel(x,k) :: T1 T2 | … Nested Refinements [POPL ’12] Key to Encode Dictionary Objects (Even in Statically Typed Languages!) 86 Why JavaScript? Challenges Types via Logic Prior Refinement Types Security via Logic Looking Ahead Dependent JavaScript (DJS) [POPL ’12, OOPSLA ’12] lightweight reflection path-sensitivity dictionary objects nested refinements extensible objects flow-sensitivity prototype inheritance logical encoding JavaScript peculiarities logical encoding 87 Why JavaScript? Challenges Types via Logic JavaScript, Python, Ruby Security via Logic Looking Ahead Dependent JavaScript (DJS) [POPL ’12, OOPSLA ’12] lightweight reflection path-sensitivity dictionary objects nested refinements extensible objects flow-sensitivity prototype inheritance JavaScript peculiarities JavaScript logical encoding logical encoding 88 Why JavaScript? Challenges Types via Logic Statically Typed Languages (Java, C++, OCaml, Haskell, …) Security via Logic Looking Ahead Dependent JavaScript (DJS) [POPL ’12, OOPSLA ’12] lightweight reflection path-sensitivity dictionary objects nested refinements extensible objects flow-sensitivity prototype inheritance logical encoding JavaScript peculiarities logical encoding 89 Why JavaScript? Challenges Types via Logic Statically Typed Languages (Java, C++, OCaml, Haskell, …) Security via Logic Looking Ahead Dependent JavaScript (DJS) [POPL ’12, OOPSLA ’12] General Techniques Can Be Used to Eliminate More ERRORS path-sensitivity nested refinements flow-sensitivity 90 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Static Types via Logic TYPES Lightweight Reflection Dictionary Objects Key Technical Innovations Evaluation 91 Why JavaScript? Challenges Types via Logic Benchmarks 13 Excerpts from: JavaScript, Good Parts SunSpider Benchmark Suite Google Closure Library Security via Logic Looking Ahead LOC before/after 306 a 408 (+33%) Chosen to Stretch Expressiveness Limits of DJS 92 Why JavaScript? Challenges Types via Logic Benchmarks 13 Excerpts from: JavaScript, Good Parts SunSpider Benchmark Suite Google Closure Library 9 Browser Extensions from: [Guha et al. Oakland ’11] 2 Examples from: Google Gadgets TOTALS Security via Logic Looking Ahead LOC before/after 306 a 321 a 1,003 a 1,630 408 (+33%) 383 (+19%) 1,027 (+2%) 1,818 (+12%) 93 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Type Annotations Relatively Simple Syntactic Sugar and Type Inference Have Helped Significantly Opportunities for Improved Type Inference: • Iterative Predicate Abstraction • Bootstrap by Running Test Cases [STOP ’11] • Translating Programs from TypeScript TOTALS 1,630 1,818 (+12%) 94 Why JavaScript? Challenges Types via Logic Benchmarks 13 Excerpts from: JavaScript, Good Parts SunSpider Benchmark Suite Google Closure Library 9 Browser Extensions from: [Guha et al. Oakland ’11] 2 Examples from: Google Gadgets TOTALS Security via Logic Looking Ahead LOC Running before/after Time 306 a 321 a 1,003 a 1,630 408 (+33%) 10 sec 383 (+19%) 3 sec 1,027 (+2%) 19 sec 1,818 (+12%) 32 sec 95 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Performance Relatively Simple Optimizations So Far: • Avoid SMT Solver When Possible • Reduce Precision for Common Patterns • Rely on Nested Refinements When Needed TOTALS 1,630 1,818 (+12%) 32 sec 96 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Static Types via Logic TYPES Lightweight Reflection Dictionary Objects Key Technical Innovations Evaluation 97 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Important? Why is JavaScript Hard? PROGRAMS TYPES Static Types via Logic Security via Logic ERRORS Looking Ahead 98 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Security via Logic ERRORS Browser Extensions Types for Fine-Grained Policies 99 … New Yorker article, “The Itch,” … 100 101 PRINT 102 “?printable=true” “I want every article in print mode” 103 Third-Party Developers Customize Browser 104 105 for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, url + “?printable=true”); }} 106 Document (DOM) host-site.com ?printable=true newyorker.com 107 Document (DOM) host-site.com ?printable=true newyorker.com evil.com Network Manager Passwords Bank Accts History JavaScript Engine Other Sensitive APIs 108 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Access All Resources Policy Expressiveness 109 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Access Some Resources cannot access DOM cannot access History Policy Expressiveness 110 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead coarse-grained and uninformative! cannot access DOM cannot access History Policy Expressiveness 111 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead coarse-grained and uninformative! similar situation for other app platforms Policy Expressiveness 112 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Fine-Grained Policies Policy Expressiveness 113 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Fine-Grained Policies can write “a” elements but only “href” attribute when original “href” value starts with “newyorker.com” and is prefix of new value 114 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Language-Based Security If Language Could Enforce Some Security-Related Policies … Then Reduce Dependence On: • Testing • Code Reviews • Dynamic Checking 115 For all programs p in PROGRAMS If p has a type T in TYPES Then p does not fail with any error e in ERRORS 116 For all programs p in PROGRAMS If p has a type T in TYPES Then p does not fail with any error e in ERRORS GOAL: Eliminate Some Security-Related Errors 117 PROGRAMS TYPES But How? ERRORS GOAL: Eliminate Some Security-Related Errors 118 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Subtyping is Implication Source of Expressive Power { xType |p} { Type x|q} {x|p} {x|q} 1 2 119 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Security via Logic ERRORS Browser Extensions Types for Fine-Grained Policies 120 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Developer writes policy in logic! Static Verification (DJS) Security Expert reviews only policy User reads informative policy 121 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … request :: url:Str Str 122 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … request :: {url:Str|WhiteListed(url)} Str 123 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … eval :: s:Str Void 124 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … eval :: {s:Str|not(Tainted(s))} Void 125 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … getAttr :: elt:Element attr:Str Str 126 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … getAttr :: elt:Element {attr:Str|CanRead(elt,attr)} Str 127 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … setAttr :: elt:Element attr:Str y:Str Void 128 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … setAttr :: elt:Element attr:Str {y:Str|CanWrite(elt,attr,y)} Void 129 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Network Manager JS Engine DOM request, … eval, … getAttr, setAttr, … Refined APIs Mediate Access Typecheck Extension with Policy 130 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead forall url. not (url = “evil.com”) WhiteListed (url) finite blacklist var s = request(“evil.com”); 131 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead forall url. not (url = “evil.com”) WhiteListed (url) //: url:Str var s = request(url); might be blacklisted! 132 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead forall url. not (url = “evil.com”) WhiteListed (url) if (url != “evil.com”) { var s = request(url); } 133 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead forall url. not (url = “evil.com”) WhiteListed (url) if (url != “evil.com”) { var s = request(url); s:Str might be tainted! eval(s); } 134 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead forall url. not (url = “evil.com”) WhiteListed (url) if (url != “evil.com”) { var s = request(url); s:Str s = sanitize(s); eval(s); {s:Str|not(Tainted(s))} } STATICALLY VERIFIED! 135 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead WhiteListed (“ny.com”) WhiteListed (“golf.com”) forall url. WhiteListed (url) not (Tainted (request (url))) trust that whitelisted servers return untainted strings 136 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead WhiteListed (“ny.com”) WhiteListed (“golf.com”) forall url. WhiteListed (url) not (Tainted (request (url))) var s = request(“ny.com”); eval(s); no need to sanitize STATICALLY VERIFIED! 137 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead forall e, oldUrl, newUrl. ValueOf (e, “href”, oldUrl) ∧ StrPrefix (“newyorker.com”, oldUrl) ∧ StrPrefix (oldUrl, newUrl) CanWrite (e, “href”, newUrl) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, url + “?printable=true”); }} 138 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead ValueOf (elt, “href”, url) ∧ StrPrefix (“newyorker.com”, url) ∧ StrPrefix (url, url + “?printable=true”) CanWrite (e, “href”, url+“?printable=true”) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, url + “?printable=true”); }} 139 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead ValueOf (elt, “href”, url) ∧ StrPrefix (“newyorker.com”, url) ∧ StrPrefix (url, url + “?printable=true”) CanWrite (e, “href”, url+“?printable=true”) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, url + “?printable=true”); }} 140 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead ValueOf (elt, “href”, url) ∧ StrPrefix (“newyorker.com”, url) ∧ StrPrefix (url, url + “?printable=true”) CanWrite (e, “href”, url+“?printable=true”) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, url + “?printable=true”); }} 141 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead ValueOf (elt, “href”, url) ∧ StrPrefix (“newyorker.com”, url) ∧ StrPrefix (url, url + “?printable=true”) CanWrite (e, “href”, url+“?printable=true”) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, url + “?printable=true”); }} STATICALLY VERIFIED! 142 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead ValueOf (elt, “href”, url) ∧ StrPrefix (“newyorker.com”, url) ∧ StrPrefix (url, url + “?printable=true”) CanWrite (e, “href”, url+“?printable=true”) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, “evil.com”); }} 143 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead ValueOf (elt, “href”, url) ∧ StrPrefix (“newyorker.com”, url) ∧ StrPrefix (url, “evil.com”) CanWrite (e, “href”, “evil.com”) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, “evil.com”); }} 144 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead ValueOf (elt, “href”, url) ∧ StrPrefix (“newyorker.com”, url) ∧ StrPrefix (url, “evil.com”) CanWrite (e, “href”, “evil.com”) for (var elt in doc.getEltsByTagName(“a”)) { var url = elt.getAttr(“href”); if (url.match(/^newyorker.com/)) { elt.setAttr(“href”, “evil.com”); }} 145 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Preliminary Benchmarks Secure Extensions Written in OCaml Types for Security + JavaScript Verification [ESOP ’10, Guha et al. ’11] [POPL ’12, OOPSLA ’12] = Fine-Grained Web Security [current] 146 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Preliminary Benchmarks Secure Extensions Written in OCaml Ported to DJS (~400 LOC so far) Well-typed programs Guha et al. ’11] don’t have run-time errors and conform to security policies 147 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Security via Logic ERRORS Browser Extensions Types for Fine-Grained Policies 148 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Outline Why is JavaScript Important? Why is JavaScript Hard? PROGRAMS TYPES Static Types via Logic Security via Logic ERRORS Looking Ahead 149 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead >>> Web Platform Dependent JavaScript 150 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead >>> Web Platform Dependent JavaScript Policy Specification 151 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Developer must write policy Static Verification (DJS) Security Expert and User must read policy 152 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Developer must write policy • Infer from traces • Incentives from platform Security Expert must read policy • Modeling tools to analyze policies User must read policy • Traces to demonstrate behavior • Community review-and-recommend services 153 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead >>> Web Platform Dependent JavaScript Policy Dynamic Specification Enforcement 154 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Developer Static Verification (DJS) Security Expert User 155 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead … eval(“…”); … Dynamic Code Loading Impossible to statically analyze code you don’t have! 156 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Developer Static Verification (DJS) Security Expert User Dynamic Enforcement 157 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead … Old Types eval(“…”); //: #assume New Types New Types … Dynamic Enforcement 158 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Limits of Static Reasoning “actual” “expected” p q Definitely Safe p q Maybe Unsafe (But Maybe Safe…) 159 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Limits of Static Reasoning “actual” “expected” p q Definitely Safe p q Maybe Unsafe p q Definitely Unsafe 160 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Limits of Static Reasoning • Accept Program, Rather than Reject • Rely on Programmer-Trusted or • Dynamically-Checked Assumption p q Maybe Unsafe Dynamic Enforcement 161 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead >>> Web Platform Dependent JavaScript Policy Dynamic Specification Enforcement Trus t Base 162 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Developer Static Verification (DJS) Security Expert reviews only policy User Dynamic Enforcement 163 Why JavaScript? Challenges Types via Logic Static Verification (DJS) Security via Logic Looking Ahead trust Security Expert reviews only policy trust SMT Solver 164 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Eliminate from TCB via Formal Verification trust Static Verification (DJS) Security Expert trust SMT Solver Eliminate from TCB à la Proof-Carrying Code [PLDI ’10] 165 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead >>> Web Platform Dependent JavaScript Tool Support Policy Dynamic Specification Enforcement Trus t Base 166 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Tools for Web Development • Generate Tests and Find Bugs for Unannotated Programs • Support Refactoring and Code Completion for Annotated Programs • Provide Analysis and Documentation Tools for Large, Popular Libraries like jQuery • Web-Based Interfaces to Collect Statistics about Programming Patterns, Errors 167 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Inferred Annotations are in Comments Flow-Sensitive Type Information by Hovering over Program Point 168 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Inferred Annotations are in Comments Flow-Sensitive Type Information by Hovering over Program Point Many Software Engineering Challenges! 169 Why JavaScript? Challenges Types via Logic Security via Logic Looking Ahead Web Platform Dependent JavaScript Tool Support Policy Dynamic Specification Enforcement Trus t Base 172 PL Techniques Program Analysis for Security [ESOP ’10] [PLDI ’10] [PLDI ’09] Dataflow Analysis for Race Detection [STOP ’11] [POPL ’12] [OOPSLA ’12] [ML ’13] [PLDI ’08] 173 Thanks! Dynamic Languages are Pervasive DJS: Precise Static Types via Logic Towards Fine-Grained Web Security ravichugh.com 174 175