Gradual Information Flow Typing Tim Disney Cormac Flanagan University of California Santa Cruz January 29th, 2011 - STOP 2011
Combining gradual typing with information flow Gradual Information + Typing Flow = More secure software
Perfect world Security designed upfront
Perfect world Security designed upfront vs. Broken world Security bolted on after the fact
Requirements Design Implementation Verification Maintenance
Finding security requirements upfront is often not economically feasible
Perfect world Broken world
Do not want Perfect world Broken world
Does not exist Do not want Perfect world Broken world
Real world Security evolves with program Does not exist Do not want Perfect world Broken world
Information Flow Confidentiality: keeping sensitive data private & Integrity: protect against untrusted data
Information Flow Confidentiality: keeping sensitive data private & Integrity: protect against untrusted data For this talk we focus on confidentiality
Information Flow Labels H (private) L (public)
Information Flow Labeled Values Labels H (private) 42 L 58,000 H “hello” L L (public)
Gradual Typing Dynamically Statically typed program typed program Siek and Taha (2006), Findler and Felleisen (2002), Wadler and Findler (2009), Ahmed et al. (2011), etc.
Gradual Typing Dynamically Mixed Statically typed program static/dynamic typed program Program fail with blame Casts Dynamically Statically typed modules typed modules Siek and Taha (2006), Findler and Felleisen (2002), Wadler and Findler (2009), Ahmed et al. (2011), etc.
Gradual Typing Dynamically Statically Mixed typed program typed program static/dynamic Program fail with blame Casts Dynamically Statically typed modules typed modules Siek and Taha (2006), Findler and Felleisen (2002), Wadler and Findler (2009), Ahmed et al. (2011), etc.
No security Gradual Security checks Static Dynamic security types security checks
No security Gradual Security checks Mixed static/ Static Dynamic dynamic security security types security checks Program fail with blame Casts Dynamic Static security modules security modules
No security Gradual Security rev 0 checks Mixed static/ Static Dynamic dynamic security security types security checks Program fail with blame Casts Dynamic Static security modules security modules
No security Gradual Security rev 0 checks Mixed static/ Static Dynamic dynamic security security types security checks rev 1 Program fail with blame Casts Dynamic Static security modules security modules
No security Gradual Security rev 0 checks Mixed static/ Static Dynamic dynamic security security types security checks rev 1 rev 2 Program fail with blame Casts Dynamic Static security modules security modules
No security Gradual Security rev 0 checks Mixed static/ Static Dynamic dynamic security security types security checks rev 1 rev 2 rev 3 Program fail with blame Casts Dynamic Static security modules security modules
A language for g radual i nformation f low
The language Values (r): Labeled Values (v): 42 H , ( λ x : A. t ) L Types (a, b): Int , Bool , A → B Labeled Types (A, B): Int L , Bool L , ( A → B ) H
The language Private types: Int H = { 0 L , 0 H , 1 L , 1 H , . . . } potentially private
The language Private types: Int H = { 0 L , 0 H , 1 L , 1 H , . . . } potentially private Public types: Int L = { 0 L , 1 L , 2 L , . . . } definitely public
The language Private types: Int H = { 0 L , 0 H , 1 L , 1 H , . . . } potentially private Public types: Int L = { 0 L , 1 L , 2 L , . . . } definitely public Subtypes
The language Default labels are permissive
The language Default labels are permissive 42 = 42 L
The language Default labels are permissive 42 = 42 L Int = Int H
The language Default labels are permissive 42 = 42 L Int = Int H
The language Default labels are permissive 42 = 42 L Int = Int H
Casting checks runtime labels t : A ⇒ p B Syntax similar to “Blame For All” by Ahmed et al.
Casting checks runtime labels t : A ⇒ p B 42 L : Int H ⇒ p Int L 42 L Syntax similar to “Blame For All” by Ahmed et al.
Casting checks runtime labels t : A ⇒ p B 42 L : Int H ⇒ p Int L 42 L 42 H : Int H ⇒ p Int L blame p Syntax similar to “Blame For All” by Ahmed et al.
Higher-order casting: cast at fault ( fn ): ( Int L → Int H ) ⇒ p ( Int L → Int L ) wrap fn
Higher-order casting: cast at fault ( fn ): ( Int L → Int H ) ⇒ p ( Int L → Int L ) wrap fn fn = λ x : Int L . x + 1 L ( wrap fn ) 42 L 43 L
Higher-order casting: cast at fault ( fn ): ( Int L → Int H ) ⇒ p ( Int L → Int L ) wrap fn fn = λ x : Int L . x + 1 L ( wrap fn ) 42 L 43 L fn = λ x : Int L . x + 1 H cast blamed ( wrap fn ) 42 L blame p
Higher-order casting: context at fault ( fn ): ( Int L → Int L ) ⇒ p ( Int H → Int L ) wrap fn
Higher-order casting: context at fault ( fn ): ( Int L → Int L ) ⇒ p ( Int H → Int L ) wrap fn 24 L ( wrap fn ) 42 L
Higher-order casting: context at fault ( fn ): ( Int L → Int L ) ⇒ p ( Int H → Int L ) wrap fn 24 L ( wrap fn ) 42 L ( wrap fn ) 42 H blame p context blamed
Labeling adds runtime labels V (58000 L : Int L V Int H ) 58000 H
Labeling adds runtime labels V (58000 L : Int L V Int H ) 58000 H disk read : ( Int L → Int L ) V ( Int L → Int H ) wrap fn
Evolution Example
Rev 0 (no security) let intToString : Int → Str = . . .
Rev 0 (no security) let intToString : Int → Str = . . . let age : Int = 42
Rev 0 (no security) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000 // confidential!
Rev 0 (no security) let intToString : Int → Str = . . . let age : Int = 42 // confidential! let salary : Int = 58000 let print : Str → Unit = λ s : Str . . . .
Rev 0 (no security) let intToString : Int → Str = . . . let age : Int = 42 // confidential! let salary : Int = 58000 let print : Str → Unit = λ s : Str . . . . print ( intToString ( salary ))
Rev 0 (no security) let intToString : Int → Str = . . . let age : Int = 42 // confidential! let salary : Int = 58000 let print : Str → Unit = λ s : Str . . . . print ( intToString ( salary )) Prints “58000”
Rev 0 (no security) let intToString : Int → Str = . . . let age : Int = 42 // confidential! let salary : Int = 58000 let print : Str → Unit = λ s : Str . . . . print ( intToString ( salary )) Prints “58000”
Add dynamic enforcement
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . print ( intToString ( salary ))
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . print ( intToString ( salary ))
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . print ( intToString ( salary )) Still prints “58000” H
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . print ( intToString ( salary )) Still prints “58000” H
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . let s = ( s : Str H ⇒ p Str L ) in . . . print ( intToString ( salary ))
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . let s = ( s : Str H ⇒ p Str L ) in . . . print ( intToString ( salary ))
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . let s = ( s : Str H ⇒ p Str L ) in . . . print ( intToString ( salary )) Fails and blames p since Str H can’t be cast to Str L
Rev 1 (dynamic enforcement) let intToString : Int → Str = . . . let age : Int = 42 let salary : Int = 58000: Int L V Int H let print : Str → Unit = λ s : Str . . . . let s = ( s : Str H ⇒ p Str L ) in . . . print ( intToString ( salary )) Fails and blames p since Str H can’t be cast to Str L
Add static enforcement
Rev 2 (static enforcement) let intToString : Int H → Str H = . . . let age : Int L = 42 let salary : Int H = 58000: Int L V Int H let print : Str L → Unit L = λ s : Str L . . . . print ( intToString ( salary ))
Rev 2 (static enforcement) let intToString : Int H → Str H = . . . let age : Int L = 42 let salary : Int H = 58000: Int L V Int H let print : Str L → Unit L = λ s : Str L . . . . print ( intToString ( salary )) intToString causes compile error
Recommend
More recommend