pptx - People.cs.uchicago.edu

advertisement
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
pq
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
Download