SLIDE 1 Gradual Information Flow Typing
Tim Disney Cormac Flanagan University of California Santa Cruz January 29th, 2011 - STOP 2011
SLIDE 2 Combining gradual typing with information flow
Information Flow Gradual Typing
+ = More secure software
SLIDE 3
Perfect world Security designed upfront
SLIDE 4
Perfect world Security designed upfront Broken world Security bolted on after the fact vs.
SLIDE 5 Requirements Design Implementation Verification Maintenance
SLIDE 6
Finding security requirements upfront is often not economically feasible
SLIDE 7
Perfect world Broken world
SLIDE 8 Perfect world Broken world
Do not want
SLIDE 9 Perfect world Broken world
Do not want Does not exist
SLIDE 10 Real world Security evolves with program Perfect world Broken world
Do not want Does not exist
SLIDE 11
Confidentiality: keeping sensitive data private & Integrity: protect against untrusted data
Information Flow
SLIDE 12
Confidentiality: keeping sensitive data private & Integrity: protect against untrusted data
Information Flow
For this talk we focus on confidentiality
SLIDE 13
Labels L (public) H (private)
Information Flow
SLIDE 14
Labels L (public) H (private) Labeled Values 42L 58,000H “hello”L
Information Flow
SLIDE 15 Dynamically typed program Statically typed program
Siek and Taha (2006), Findler and Felleisen (2002), Wadler and Findler (2009), Ahmed et al. (2011), etc.
Gradual Typing
SLIDE 16 Dynamically typed program Statically typed program
Siek and Taha (2006), Findler and Felleisen (2002), Wadler and Findler (2009), Ahmed et al. (2011), etc.
Gradual Typing
Dynamically typed modules Statically typed modules Program
Casts
Mixed static/dynamic
fail with blame
SLIDE 17 Dynamically typed program Statically typed program
Siek and Taha (2006), Findler and Felleisen (2002), Wadler and Findler (2009), Ahmed et al. (2011), etc.
Gradual Typing
Dynamically typed modules Statically typed modules Program
Casts
Mixed static/dynamic
fail with blame
SLIDE 18 Static security types No security checks Dynamic security checks
Gradual Security
SLIDE 19 Static security types No security checks Dynamic security checks Dynamic security modules Static security modules Program
Casts
Mixed static/ dynamic security
fail with blame
Gradual Security
SLIDE 20 Static security types No security checks Dynamic security checks Dynamic security modules Static security modules Program
Casts
Mixed static/ dynamic security
fail with blame
Gradual Security
rev 0
SLIDE 21 Static security types No security checks Dynamic security checks Dynamic security modules Static security modules Program
Casts
Mixed static/ dynamic security
fail with blame
Gradual Security
rev 0 rev 1
SLIDE 22 Static security types No security checks Dynamic security checks Dynamic security modules Static security modules Program
Casts
Mixed static/ dynamic security
fail with blame
Gradual Security
rev 0 rev 1 rev 2
SLIDE 23 Static security types No security checks Dynamic security checks Dynamic security modules Static security modules Program
Casts
Mixed static/ dynamic security
fail with blame
Gradual Security
rev 0 rev 1 rev 2 rev 3
SLIDE 24
A language for gradual information flow
SLIDE 25 The language
Types (a, b): Labeled Types (A, B):
Int, Bool, A → B
Values (r): Labeled Values (v): 42H, (λx:A. t)L
IntL, BoolL, (A → B)H
SLIDE 26 The language
Private types: potentially private
IntH = {0L, 0H, 1L, 1H, . . .}
SLIDE 27 The language
Private types: potentially private
IntH = {0L, 0H, 1L, 1H, . . .}
Public types: definitely public
IntL = {0L, 1L, 2L, . . .}
SLIDE 28 The language
Private types: potentially private
IntH = {0L, 0H, 1L, 1H, . . .}
Public types: definitely public
IntL = {0L, 1L, 2L, . . .}
Subtypes
SLIDE 29
The language
Default labels are permissive
SLIDE 30
The language
Default labels are permissive
42 = 42L
SLIDE 31
The language
Default labels are permissive
Int = IntH
42 = 42L
SLIDE 32
The language
Default labels are permissive
Int = IntH
42 = 42L
SLIDE 33
The language
Default labels are permissive
Int = IntH
42 = 42L
SLIDE 34 Casting checks runtime labels
Syntax similar to “Blame For All” by Ahmed et al.
t: A ⇒p B
SLIDE 35 Casting checks runtime labels
42L : IntH ⇒p IntL
42L
Syntax similar to “Blame For All” by Ahmed et al.
t: A ⇒p B
SLIDE 36 Casting checks runtime labels
42L : IntH ⇒p IntL
42L
Syntax similar to “Blame For All” by Ahmed et al.
t: A ⇒p B
42H : IntH ⇒p IntL
blame p
SLIDE 37 Higher-order casting: cast at fault
wrap fn
(fn): (IntL → IntH) ⇒p (IntL → IntL)
SLIDE 38 Higher-order casting: cast at fault
wrap fn
(fn): (IntL → IntH) ⇒p (IntL → IntL)
43L
fn = λx:IntL. x + 1L
(wrap fn) 42L
SLIDE 39 Higher-order casting: cast at fault
wrap fn
(fn): (IntL → IntH) ⇒p (IntL → IntL)
blame p
(wrap fn) 42L cast blamed
fn = λx:IntL. x + 1H
43L
fn = λx:IntL. x + 1L
(wrap fn) 42L
SLIDE 40 Higher-order casting: context at fault
wrap fn
(fn): (IntL → IntL) ⇒p (IntH → IntL)
SLIDE 41 Higher-order casting: context at fault
wrap fn
(wrap fn) 42L
24L
(fn): (IntL → IntL) ⇒p (IntH → IntL)
SLIDE 42 Higher-order casting: context at fault
wrap fn
(wrap fn) 42L
24L
(wrap fn) 42H
blame p
context blamed (fn): (IntL → IntL) ⇒p (IntH → IntL)
SLIDE 43 (58000L : IntL V IntH)
58000H
Labeling adds runtime labels
V
SLIDE 44 (58000L : IntL V IntH)
58000H
Labeling adds runtime labels
V
disk read : (IntL → IntL) V (IntL → IntH)
wrap fn
SLIDE 45
Evolution Example
SLIDE 46
Rev 0 (no security)
let intToString : Int → Str = . . .
SLIDE 47
Rev 0 (no security)
let intToString : Int → Str = . . . let age : Int = 42
SLIDE 48
Rev 0 (no security)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000 // confidential!
SLIDE 49
Rev 0 (no security)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000 let print : Str → Unit = λs:Str. . . .
// confidential!
SLIDE 50
Rev 0 (no security)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000 let print : Str → Unit = λs:Str. . . . print(intToString(salary))
// confidential!
SLIDE 51
Prints “58000”
Rev 0 (no security)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000 let print : Str → Unit = λs:Str. . . . print(intToString(salary))
// confidential!
SLIDE 52
Prints “58000”
Rev 0 (no security)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000 let print : Str → Unit = λs:Str. . . . print(intToString(salary))
// confidential!
SLIDE 53
Add dynamic enforcement
SLIDE 54
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . print(intToString(salary))
SLIDE 55
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . print(intToString(salary))
SLIDE 56
Still prints “58000”H
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . print(intToString(salary))
SLIDE 57
Still prints “58000”H
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . print(intToString(salary))
SLIDE 58
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . let s = (s: StrH ⇒p StrL) in . . . print(intToString(salary))
SLIDE 59
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . let s = (s: StrH ⇒p StrL) in . . . print(intToString(salary))
SLIDE 60
Fails and blames p since StrH can’t be cast to StrL
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . let s = (s: StrH ⇒p StrL) in . . . print(intToString(salary))
SLIDE 61
Fails and blames p since StrH can’t be cast to StrL
Rev 1 (dynamic enforcement)
let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: IntL V IntH let print : Str → Unit = λs:Str. . . . let s = (s: StrH ⇒p StrL) in . . . print(intToString(salary))
SLIDE 62
Add static enforcement
SLIDE 63
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . print(intToString(salary))
SLIDE 64
intToString causes compile error
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . print(intToString(salary))
SLIDE 65
intToString causes compile error
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . print(intToString(salary))
SLIDE 66
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(salary))
SLIDE 67
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(salary))
SLIDE 68
salary causes compile error
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(salary))
SLIDE 69
salary causes compile error
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(salary))
SLIDE 70
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(age))
SLIDE 71
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(age))
SLIDE 72
Compiles successfully
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(age))
SLIDE 73
Compiles successfully
Rev 2 (static enforcement)
let intToString : IntH → StrH = . . . let age : IntL = 42 let salary : IntH = 58000: IntL V IntH let print : StrL → UnitL = λs:StrL. . . . let intToStringL : IntL → IntL = intToString: (IntH → IntH) ⇒p (IntL → IntL) print(intToStringL(age))
SLIDE 74
Safety Theorems
SLIDE 75
Theorem: Termination Insensitive Non-Interference Private inputs cannot affect public outputs
See paper for details
SLIDE 76
Subtyping
L v H L v L H v H
SLIDE 77 Subtyping
L v H L v L H v H
l v k Intl <: Intk
Subtype
SLIDE 78 Subtyping
L v H L v L H v H
l v k Intl <: Intk
Subtype Positive Subtype
l v k Intl <:+ Intk
SLIDE 79 Subtyping
L v H L v L H v H
l v k Intl <: Intk
Subtype Positive Subtype
l v k Intl <:+ Intk
Negative Subtype
k v l Intl <:− Intk
SLIDE 80
Blame Theorem If two types are subtypes, casting cannot cause blame
SLIDE 81 Blame Theorem
- 1. If t: A ⇒p B and A <: B then never blames p or p
- 2. If t: A ⇒p B and A <:+ B then never blames p
- 3. If t: A ⇒p B and A <:− B then never blames p
If two types are subtypes, casting cannot cause blame
SLIDE 82 Conclusion
- Gradually evolve security
- From dynamic info-flow to static info-flow
- Provide language features to allow security
evolution