Secure Information Flow for Reactive Programming Paradigm Zhengqin Luo SAFA workshop 2009
What is this talk about? Secure information flow problem Programs can access confidential information Some of programs’ behaviors are publicly observation Reactive Programming Paradigm Deterministic concurrency, cooperative scheduling Synchronized threads, signals, suspensions, preemptions Controlling information flow for reactive programs How information can be deliberately leaked? How to prevent insecure flows? Dynamic and static enforcement SAFA workshop 2009
Secure information flow problem Programs interact with confidential information Non-interference property Inputs/outputs are classified by secret and public Differs in secret inputs SHOULD NOT result in different public output A simplified lattice model: L (public), H (secret) P P Credit card No., price Other cookies Auction.com Steal-your-informaion.com P P Secret Public Secret Public SAFA workshop 2009
Typical insecure programs High-order imperative ML notion u L is public; v H is confidential Direct flow u L :=!v H Indirect flow If !v H then u L :=0 else u L :=1 Indirect flow with thread creation If !v H then (thread (u L :=0)) else (thread (u L :=1)) Caution! Carefully check your programs! SAFA workshop 2009
Reactive Programming Paradigm - Informal Based on high-order imperative ML An reactive machine contains Environment ξ : a set of emitted signals Thread pool : Reactive construct (emit s) (when s do N) - suspension (watch s do N) - preemption Cooperative scheduling (deterministic) For example: a round-robin one Computations are divided by instants SAFA workshop 2009
Reactive Programming Paradigm - Informal * * Suspension: t1’ is waiting for some signal s, which is not in ξ1, (when s do M) A cooperative round-robin scheduler All threads are suspended Instant transition: perform preemption t=(watch s do M) => t=(), if s is in ξ2 Instant 1 * Instant 2 Reset signal environment SAFA workshop 2009
Insecure examples (1/2) – suspension T1: If !h then (emit s) else (); when s do (l:=1) T2: l:=2 ; emit s h= true in the initial memory T1 || T2, Ø → when s do (l:=1) || l:=2 ; emit s, {s} → when s do () || l:=2 ; emit s, {s}(l:=1) → () || l:=2 ; emit s, {s} → () || emit s, {s}(l:=2) → () || (), {s} SAFA workshop 2009
Insecure examples (1/2) – suspension T1: If !h then (emit s) else (); when s do (l:=1) T2: l:=2 ; emit s h= false in the initial memory T1 || T2, Ø → when s do (l:=1) || l:=2 ; emit s, Ø → when s do (l:=1) || emit s, Ø (l:=2) → when s do (l:=1) || (), {s} → when s do () || (), {s} (l:=1) → () || (), {s} SAFA workshop 2009
Insecure examples (1/2) – suspension T1: If !h then (emit s) else (); when s do (l:=1) T2: l:=2 ; emit s T1 || T2 is not secure by non-interference Key observation Signals carry information Testing signals gets information Suspension may change the order of observable actions SAFA workshop 2009
Insecure programs (2/2) – preemption T1: (watch s do (when t do (l:=1))) T2: l:=2; if !h then (emit s) else (); pause; emit t h=false in the initial memory T1 || T2, Ø → T1 || T2, Ø → T1 || if !h then (emit s) else (); pause; emit t, Ø (l:=2) → (watch s do (when t do (l:=1))) || pause; emit t, Ø → (watch s do (when t do (l:=1))) || () ; emit t, Ø → (watch s do (when t do (l:=1))) || (), {t} → (watch s do (when t do ())) || (), {t} (l:=1) → () || (), {t} SAFA workshop 2009
Insecure programs (2/2) – preemption T1: (watch s do (when t do (l:=1))) T2: l:=2; if !h then (emit s) else (); pause; emit t h=true in the initial memory T1 || T2, Ø → T1 || T2, Ø → T1 || if !h then (emit s) else (); pause; emit t, Ø (l:=2) → (watch s do (when t do (l:=1))) || pause; emit t, {s} → () || () ; emit t, Ø → () || (), {t} SAFA workshop 2009
Insecure programs (2/2) – preemption T1: (watch s do (when t do (l:=1))) T2: l:=2; if !h then (emit s) else (); pause; emit T1 || T2 is not secure by non-interference Key observation Preemption may change whether an observable actions is executed or not SAFA workshop 2009
Our solution Consider signal environment as part of the inputs/outputs (memory) s= true s is emitted Classify signals with security level s L, s H, t L, t H … Then some of the programs should be rejected if !x H then (emit s L ) else (emit t L ) when s H do x L :=1; watch s H do (…(x L :=1)...) IS THAT ALL? SAFA workshop 2009
Our solutions – more subtle case Recall the insecure suspension example T1: If !h then (emit s) else (); when s do (l:=1) T2: l:=2 ; emit s An slightly modified version T1: If !h then (emit s) else (); when s do (); l:=1 T2: l:=2 ; emit s Observation: suspension construct will not only possible to reorder its body, but also all the computation afterward. We should also reject (when s H do …);…;x L :=1; SAFA workshop 2009
Secure Information flow as a safety property Non-interference, bisimulation Comparing two execution of programs, a non-stand property Intuitive notion of secure information flow “one should not put in a public location a value elaborated using confidential information”,[DD77] A monitoring semantics Keep track of the level of information gained along the computation Run-time error: trying to assign to public location when the level recorded is more confidential Secure information as a safety property [Bou08] No such error occurs! SAFA workshop 2009
A monitoring semantics We extend the standard semantics with dynamic checks for insecure information flow To keep track of information, each thread are extend by two variables (independent for each thread) t=(pc,cur,M) where pc,cur ∈ {L,H} pc stands for the level of information that will affect the functional and imperative behavior of the thread cur stands for the level of information that will affect the reactive behavior of the thread SAFA workshop 2009
How pc is manipulated - example The same as in [Bou08] Example: (L,L, (if !x H then y H := 1 else ()); z L :=1) → (L,L, (if !x H then y H := 1 else ()); (z L :=1) L ) → (H,L, (if tt then y H := 1 else ()); (z L :=1) L ) → (H,L, (y H := 1); (z L :=1) L ) → (H,L, (); (z L :=1) L ) → (L,L, z L :=1) Similar cases for other constructs Security check happens here, if it is (y L :=1), the check will fail pc is forgotten pc is transmitted pc is increased SAFA workshop 2009
How cur is manipulated Testing a signal by when (the case by watch is similar) (pc,cur,when s l do N) → (pc,pc\/cur\/l, when do N) Why pc is added to cur? Examples: (L, L, if !x H then (when s L do N) else (when t L do N)) → (H, L, if tt then (when s L do N) else (when t L do N)) → (H, L, (when s L do N) ) → (H, H, (when do N) ) But cur is never forgotten! Compare (when s do N) and (when s do ());N They have essentially the same effect to reorder instructions in case of suspension SAFA workshop 2009
Is the monitoring secure enough? Consider this example: If u H then when s H do () else (); !x L () || x L := λ_.(); emit s L where x L = λ_.(y L :=1), and y L :=0 initially It is safe by the monitoring semantics If u H then when s H do () else (); !x L () || x L := λ_.(); emit s L Why is that? Monitoring only learns information in one branch of conditional constructs. ①②③④⑤ ①②③④⑤ SAFA workshop 2009
A type directed translation An special programming construct (P M) for the target language In the standard semantics M->M’ => (P M) → (P M’) (P V) → V In the monitoring semantics (pc,cur,(P V)) → (pc,pc\/cur, V) SAFA workshop 2009
A type directed translation How does the translation work? Suppose we have (if !h then M else N) and M will suspend while N will not The translation is (if !h then M else (P N)) The subtle example again Remember (pc,cur,(P V)) → (pc,pc\/cur, V) If u H then when s H do () else (P ()); !x L () || x L := λ_.(); emit s L ①②③④⑤ ①②③ SAFA workshop 2009
A particular reactive programming High-order imperative language with reactive construct An reactive machine is M =[μ,ξ,t,T] μ is the store, ξ is the signal environment t=(i,M) is the current running thread T is the thread pool M,N ::= V | (if M then N else N’) | (MN) | (M;N) | (ref M) | (!M) | (M:=N) | (thread M) | (sig) | (emit M) | | (when M do N) | (watch M do N) V ::= λxM | s l | u l | tt | ff | () SAFA workshop 2009
Security enforced by dynamic monitoring Definition: Progress-insensitive security [SR09] A symmetric relation R on reactive machines M 1 =[μ 1,ξ 1,t 1,T 1 ] R M 2 =[μ 2,ξ 2,t 2,T 2 ] , iff 1) μ 1 = L μ 2, ξ 1 = L ξ 2 2) if M 1 → M’ 1, either there exists M 2 → * M’ 2,such that M’ 1 R M’ 2 or for all M’ 2 =[μ’ 2,ξ’ 2,t’ 2,T’ 2 ] such that M 2 → * M’ 2, μ’ 2 = L μ’ 2, ξ’ 1 = L ξ’ 2 Definition: Safe programs Does not run into security error in monitoring semantics Our results (informal) Theorem: For every programs M that its translation M’ is safe, then for every μ 1 = L μ 2, ξ 1 = L ξ 2, we have [μ 1,ξ 1,(0,M’), Ø] R [μ 2,ξ 2, (0,M’), Ø] SAFA workshop 2009
A type and effect system for safety We also designed a type and effect system for a sound analysis of safety property A fairly standard one extend the one for high-order language Our results Lemma: If a program is typable then its translation is safe Lemma: The semantics of typable program is almost identical to its translation in the monitoring semantics Theorem: Typable programs itself satisfy progress- insensitive security SAFA workshop 2009
Conclusion Controlling information flow in reactive programs Dynamically checking information – A monitoring semantics Does not imply any security property A simple type-directed translation If translated program is safe, then it satisfy progress- insensitive security A type safety result Type-checked program => no need for monitoring SAFA workshop 2009
Thank you! Q & A SAFA workshop 2009