Gradual Security Typing with References
Total Page:16
File Type:pdf, Size:1020Kb
2013 IEEE 26th Computer Security Foundations Symposium Gradual Security Typing with References Luminous Fennell, Peter Thiemann Dept. of Computing Science University of Freiburg Freiburg, Germany Email: {fennell, thiemann}@informatik.uni-freiburg.de Abstract—Type systems for information-flow control (IFC) The typing community studies a similar interplay between are often inflexible and too conservative. On the other hand, static and dynamic checking. Gradual typing [25], [26] is dynamic run-time monitoring of information flow is flexible and an approach where explicit cast operations mediate between permissive but it is difficult to guarantee robust behavior of a program. Gradual typing for IFC enables the programmer to coexisting statically and dynamically typed program frag- choose between permissive dynamic checking and a predictable, ments. The type of a cast operation reflects the outcome of conservative static type system, where needed. the run-time test performed by the cast: The return type of We propose ML-GS, a monomorphic ML core language with the cast is the compile-time manifestation of the positive test; references and higher-order functions that implements gradual a negative outcome of the test causes a run-time exception. typing for IFC. This language contains security casts, which enable the programmer to transition back and forth between Disney and Flanagan propose an integration of security static and dynamic checking. types with dynamic monitoring via gradual typing [11]. Such In particular, ML-GS enables non-trivial casts on reference an integration enables the stepwise introduction of checked types so that a reference can be safely used everywhere in a security policies into a software system. The programmer program regardless of whether it was created in a dynamically inserts checks for these policies as run-time casts at strategic or statically checked part of the program. The reference can be shared between dynamically and statically checked parts. points in the code. The type system statically guarantees We prove the soundness of the gradual security type system adherence to the policies “on the static side” of a cast, along with termination insensitive non-interference. whereas the run-time system checks the policies “on the Keywords-gradual typing; security typing; ML; references dynamic side”. This procedure creates statically checked regions in a I. INTRODUCTION dynamically checked environment. These regions can be en- Language-based analysis and control of information flow larged by rewriting code and moving casts to make programs in software systems has been studied by numerous authors more efficient and to avoid potential run-time errors. [13], [23]. Many studies propose type-based, static program Alternatively, a programmer may impose a static secu- analyses where the non-interference property is guaranteed rity typing discipline on a program and revert to dynamic for well-typed programs. Other studies concentrate on dy- checking by inserting casts demarcating the regions where namic monitoring of program execution where potentially the static checker fails. This approach leads to dynamically interfering behavior of a program is detected and prevented checked regions and the programmer should strive to restrict at run time. Hybrid approaches (e.g., [12], [22]) combine them to places where the static analysis would be too both kinds of analysis. conservative or where the code contains language features Static approaches are advantageous for the specification not supported by the analysis. The programmer may also of security policies that are known up-front and where restrict debugging efforts that chase policy violations to the the program can be built to suit the analysis. The analy- dynamically checked parts. sis guarantees that no security mismatches happen at run time. However, security policies are often formulated as A. Contributions an afterthought, when a large part of a system is already Disney and Flanagan [11] consider a pure lambda cal- implemented, or they may evolve as the implications of a culus. Building on their ideas, we study a monomorphic system design become understood. Unfortunately, a program ML core language with references. The consideration of ref- that was not built with the static analysis in mind can be erences introduces significant complications, as references difficult to modify so that it accepted by the analysis even enable flow-sensitivity attacks [22]. The underlying type though the program respects the desired security policies. system is inspired by Pottier and Simonet’s work on a Dynamic approaches, on the other hand, enforce a safe security type system for CoreML [21]. We extend this static approximation to the non-interference property. They do not system with casts and suitable run-time representations of give static guarantees, but are amenable to changes in the security levels on the dynamic side of a cast. Our casts are security policy without requiring a rewrite of the code. very powerful because they are able to change the security © 2013, Luminous Fennell. Under license to IEEE. 224 DOI 10.1109/CSF.2013.22 type of the content of a reference. This choice enables 1 (* Some privileged information *) H our calculus to safely perform casts between security types 2 let infoH : ref Report = ... that are not related by the subtype relation induced by the 3 ordering on security levels: A sound subtype relation must 4 (* Optionally enhance a report 5 with privileged information ) treat references invariantly. The extended calculus uses a no- * * 6 addPrivileged isPrivileged worker report = sensitive-upgrade strategy (NSU, [3]) for information flow 7 if isPrivileged control (IFC) on the dynamic side and we prove termination 8 then report := report + !infoH; insensitive non-interference for the combined system. 9 worker report Listing 1. Example function with manual security enforcement. B. Terminology Security levels are drawn from a two-element lattice with elements L for low-security, public information and H for requiring any run-time checks. Here are two examples of high-security, secret information. They are ordered by L @ H such procedures with their type signatures:1 and the operator t denotes the least upper bound. Our results H H generalize to arbitrary discrete security lattices as outlined sendToManager : ref Report → unit L for CoreML [21]. In the remainder of the paper, we will sendToFacebook : ref ReportL → unit use a capital “B” as a meta-variable for the security levels The sendToManager function takes a confidential report of values and a capital “PC ” for the security context.A and guarantees that it is not leaked to the public. The H on security context is the security level of the program counter the arrow indicates the lowest security level that is modified. at run-time. The sendToFacebook function takes a public report and We write intL for the type of low-security integers and L H publishes it to an open Internet message board, as indicated ref int for the type of low-security pointers that point L by the low-security effect →. H L to high-security integers in memory. The type (int → Listing 1 illustrates a proposed extension of the re- H L int ) specifies a low-security function that takes a high- port processing application. It contains a utility function security argument and yields a high-security result. The addPrivileged that adds privileged information to a report annotation on the arrow restricts the effect of the function, before passing it to a procedure like sendToManager or i.e., the function allocating or modifying a memory cell, to sendToFacebook. The flag isPrivileged indicates if the cells of at least the level indicated by the annotation. The worker argument is sufficiently trusted to handle a privi- annotation L means that all cells may be modified, whereas leged report. If isPrivileged is true, then the privileged H would restrict modification to high-security memory cells. information is retrieved through a global reference infoH Upgrading a memory cell means to overwrite its low- and added to report. Otherwise, worker is called with an security content with a high-security value. Because up- unmodified report. grades that occur in high-security contexts may leak con- Listing 1 type checks in FlowCaml and also the term fidential information through implicit flows, they have to be treated specially by dynamic IFC techniques [5]. Security addPrivileged true sendToManager type systems typically forbid upgrades altogether. is accepted with type ref ReportH→H unit, as We will employ the non-sensitive-upgrade (NSU) strategy sendToManager is safe for consuming high-security of Austin and Flanagan [3] as a dynamic IFC technique. In information. In contrast, the term an NSU semantics, assignments fail if they would upgrade a memory cell under a high-security context. addPrivileged false sendToFacebook is rejected by the type checker, even though it is semantically II. MOTIVATION safe. No privileged information is leaked, but the type The following examples illustrate the creation of dy- checker does not track the correspondence between the namically checked regions in otherwise statically checked security level of the worker and the isPrivileged flag. programs and vice versa. The motivation for the examples Our proposal for gradual security typing allows us to is to work around restrictions imposed by the underlying embed a (security-) untyped code fragment in a typed security type system, for example the dynamic, manual setting. A cast expression