Dependency-Based Information Flow Analysis with Declassification in a Program Logic
We present a deductive approach for the analysis of secure information flows with support for fine-grained policies that include declassifications in the form of delimited information release. By explicitly tracking the dependencies of program locations as a computation history, we maintain high precision, while avoiding the need for comparing independent program runs. By considering an explicit heap model, we argue that the proposed analysis can straightforwardly be applied on object-oriented programs.
💡 Research Summary
The paper introduces a deductive, dependency‑based approach to information‑flow analysis that explicitly supports fine‑grained declassification policies expressed as “delimited information release” (DIR). Traditional non‑interference policies, which forbid any flow from high‑security locations to lower‑security ones, are often too restrictive for realistic software. For example, a password checker may safely reveal whether the entered password matches the stored one, but must keep the password itself secret. DIR policies capture such controlled releases by specifying under which conditions a particular term may be disclosed.
The authors start by defining a simple imperative language together with a program logic that can specify functional properties. The logic’s signature includes sorts, function and predicate symbols, program variables (non‑rigid) and logical variables (rigid). Programs consist of assignments, conditionals, loops, and a special “update” construct that records variable modifications as explicit substitutions. Updates can be combined in parallel (u₁ || u₂) and are applied lazily after symbolic execution, enabling simplifications before they affect the post‑condition.
A key innovation is the representation of dependencies not as sets of variables but as term structures (syntactic trees). For each term t and program p, the smallest set D(t, p) of program variables is defined such that fixing the values of all variables in D(t, p) determines the final value of t after executing p. This term‑level granularity avoids the over‑approximation typical of set‑based analyses; for instance, the sequence “x := y; x := 8” yields D(x, p) = ∅ because the final value of x no longer depends on y. The authors prove that non‑interference can be reformulated: a program is non‑interfering with respect to a security lattice (L, ⊑) iff for every variable x, every y ∈ D(x, p) satisfies lvl(y) ⊑ lvl(x).
To incorporate declassification, the paper extends the logic with formulas that encode conditional releases. A DIR policy is expressed as a logical implication φ ⇒ (lvl(t) ≤ ℓ), meaning that term t may be observed at security level ℓ only when condition φ holds. The authors illustrate this with a toy decryption routine (Fig. 1) that only reveals the decrypted message if both padding and checksum checks succeed. The policy is captured by two declassifications: (i) unconditionally declassify the Boolean conjunction “paddingOk ∧ checkSumOk”, and (ii) declassify the message term only under the same conjunction.
The paper further enriches the language with object‑oriented features: objects, fields, and a heap modeled using array theory. New statements “x.f = t”, “x = t.f”, and “x = new” are introduced. The heap is represented by a global variable heap of sort Heap, with functions store and select to write and read field values. This explicit heap model enables the analysis of aliasing and field‑sensitive flows, as demonstrated in Fig. 2 where the value assigned to objC.f may affect either objA.f or objB.f depending on a secret condition.
Verification is performed in a Gentzen‑style sequent calculus that has been extended to handle programs, updates, and heap operations. The conditional rule splits a proof into two branches, assuming the guard true in one and false in the other. Assignment rules translate a concrete assignment into an update that is accumulated in front of the remaining program fragment. Heap‑related rules translate field writes into store updates and field reads into select applications. Because updates are delayed, the calculus can simplify them (e.g., eliminating redundant writes) before they are applied to the post‑condition, reducing case splits and improving automation.
Section 5 applies the framework to the two running examples. For the decryption program, the proof shows that the final result variable depends on cipher*key only when both checks succeed, matching the intended DIR policy. For the aliasing example, the proof tracks the flow from the secret h through the conditional object assignment to the field write, demonstrating that the heap model correctly captures indirect flows.
The contributions are threefold: (1) a term‑level dependency analysis that yields higher precision than traditional variable‑set approaches; (2) a logical encoding of conditional declassification that integrates seamlessly with the program logic, enabling automated verification of fine‑grained release policies; (3) an extensible treatment of heaps and objects, showing that the method can be applied to object‑oriented languages without sacrificing soundness.
The authors compare their work to earlier type‑system‑based information‑flow analyses and to their own prior work on integrating abstract interpretation with a program logic for loop invariant generation. They argue that the current approach eliminates the need for comparing multiple program runs (as required by relational semantics) and avoids the conservatism of flow‑insensitive type systems. Future work is outlined as implementing tool support, scaling the method to larger code bases, handling concurrency, and exploring richer declassification constructs.
Comments & Academic Discussion
Loading comments...
Leave a Comment