Combining Static and Dynamic Analysis for Automatic Identification of Precise Access-Control Policies Paolina Centonze IBM Watson Research Center Hawthorne, New York, USA paolina@us.ibm.com Robert J. Flynn Polytechnic University Brooklyn, New York, USA flynn@poly.edu Marco Pistoia IBM Watson Research Center Hawthorne, New York, USA pistoia@us.ibm.com Abstract Given a large component-based program, it may be very complex to identify an optimal access-control policy, allow- ing the program to execute with no authorization failures and no violations of the Principle of Least Privilege. This paper presents a novel combination of static and dynamic analysis for automatic determination of precise access- control policies for programs that will be executed on Stack- Based Access Control systems, such as Java and the Com- mon Language Runtime (CLR). The static analysis soundly models the execution of the program taking into account na- tive methods, reflection, and multi-threaded code. The dy- namic analysis interactively refines the potentially conser- vative results of the static analysis, with no need for writing or generating test cases or for restarting the system if an authorization failure occurs during testing, and no risk of corrupting the underlying system on which the analysis is performed. We implemented the analysis framework presented by this paper in an analysis tool for Java programs, called Access-Control Explorer (ACE). ACE allows for automatic, safe, and precise identification of access-right requirements and library-code locations that should be made privilege- asserting to prevent client code from requiring unnecessary access rights. This paper presents experimental results ob- tained on large production-level applications. 1 Introduction Defining the security policy of a program is a challeng- ing activity, which becomes particularly difficult when the program is large and complex and consists of multiple com- ponents. 1 Ideally, the security policy should be just suffi- 1 As an example, the Eclipse community [9] is currently undergoing a very expensive process to enable Java security on the Rich Client Platform (RCP) [10]. This requires determining the authorization and privilege- cient for the program to run without authorization failures. Any access right unnecessarily granted to the program or its users is a violation of the Principle of Least Privilege [31]. Modern component-based software systems, such as Java [27] and Microsoft .NET Common Language Runtime (CLR) [13], have adopted a form of authorization checking called Stack-Based Access Control (SBAC); when access to a restricted resource is attempted, a stack inspection ensures that all the code on the call stack is sufficiently authorized. In SBAC systems, when library code is developed, an important decision that needs to be made is whether the portion of library code requesting an access right should be made privilege-asserting. This causes the run-time stack inspection to stop at the library level. As a result, client code is exempted from the requirement to exhibit the access right requested by the library. For example, a library providing socket connections to its clients may have been programmed to log the network operations to a file. While it is reasonable to impose that the client code be granted the necessary SocketPermission, it is not reasonable to impose that any client code be granted the FilePermission to write to the log file. If client code had to be granted that FilePermission, a violation of the Principle of Least Privilege would arise; a malicious client could misuse that permission to log false informa- tion. Clearly, privilege-asserting code should be inserted cautiously because when client code is above privilege- asserting code on the stack, its access rights are not verified. Traditionally, security policies are defined using a com- bination of source-code inspection and testing. However, for large and complex programs, manual code inspections may be impractical, tedious, time consuming, and error prone. This type of analysis may even be infeasible if source code is unavailable, which is the case if the program was machine generated or written by a third party. On the other hand, testing requires writing or generating test cases, exe- assertion requirements of the entire RCP. Part of the static analysis work described in this paper has been used to facilitate that goal.