Presentation is loading. Please wait.

Presentation is loading. Please wait.

A Conservative Algorithm for Computing the Flow of Permissions in Java Programs Gleb Naumovich Polytechnic University Brooklyn, USA Presented by David.

Similar presentations


Presentation on theme: "A Conservative Algorithm for Computing the Flow of Permissions in Java Programs Gleb Naumovich Polytechnic University Brooklyn, USA Presented by David."— Presentation transcript:

1 A Conservative Algorithm for Computing the Flow of Permissions in Java Programs Gleb Naumovich Polytechnic University Brooklyn, USA Presented by David Chays Polytechnic University

2 Motivation Security problems may exist on two levels  Protocol level  Attacks exploit weakness of encryption/authentication/transfer protocols  Implementation level  Attacks exploit errors in implementation of secure protocols Java developers rely on the built-in security model to provide protection against some types of attacks  This model is complicated, so application programmers are likely to make mistakes in its use This work aims at validating the use of the Java security model by developers

3 Java security model: permissions Remotely loaded classes may be given permission to perform specific operations grant signedBy “Poly”, codebase http://cis.poly.edu/gleb/classes/- { permission java.io.FilePermission “/tmp/*”, “read, write”; }http://cis.poly.edu/gleb/classes/- Code dealing with sensitive operations (e.g. reading/writing, opening sockets) has to check that callers have sufficient permissions AccessController.checkPermission(new java.io.FilePermission( “/tmp/*”, “read, write”));

4 Permission checking: running example public class Account { private Money balance; private String persistentLocation; public Account(Money initialAmount, String persistentLocation) { AccessController.checkPermission( new NewAccountPermission ("NewAccountPermission")); this.balance = (Money) initialAmount.clone(); this.persistentLocation = persistentLocation; } public Money getBalance() { AccessController.checkPermission( new BalancePermission("BalancePermission")); return (Money) this.balance.clone(); } public void credit(Money amount) { AccessController.checkPermission( new CreditPermission("CreditPermission")); this.balance.add(amount); this.write(); } public void debit(Money amount) { AccessController.checkPermission( new DebitPermission("DebitPermission")); this.balance.subtract(amount); this.write(); } private void write() { AccessController.doPrivileged() ( new PrivilegedAction() { public Object run() { FileWriter writer = new FileWriter (this.persistentLocation); writer.write(balance); writer.close(); } ); } public void transfer(Money amount, Account toAccount) { this.debit(amount); toAccount.credit(amount); }

5 Permission checking: running example (cont.) public class AccountWithProtection extends Account { private Account protection; public AccountWithProtection(Money initialAmount, String persistentLocation, Account protection) { super(initialAmount, persistentLocation); this.protection = protection; } public void debit(Money amount) { AccessController.checkPermission( new CustomerPermission("CustomerPermission"); AccessController.doPrivileged() ( new PrivilegedAction() { public Object run() { Money currentBalance = this.getBalance(); if (currentBalance.compare(amount) == Money.LESS_THAN) { Money toTransfer = amount.clone(); toTransfer.subtract(currentBalance); this.protection.transfer(toTransfer, this); } super.debit(amount); } ); } public class CustomerInterface { public static void main(String[] args) { Account savings = new Account( new Money(3000, 0), "savings"); AccountWithProtection credit = new AccountWithProtection( new Money(5000, 0), "credit", savings); AccountWithProtection overdraft = new AccountWithProtection( new Money(1000, 0), "overdraft", credit); AccountWithProtection checking = new AccountWithProtection( new Money(2000, 0), "checking", overdraft); checking.debit(new Money(10000, 0)); }

6 How checkPermission works Examines all classes on the call stack and makes sure that all of them have permission to do an operation class MainClass { public static void main(String [] args) { … MyClass o = new MyClass(); o.m(); } class MyClass { … public void m() { … RemoteClass obj = new RemoteClass(); obj.passAccount(new Account(1000)); } MainClass main MyClass m RemoteClass passAccount Account debit } JVM makes sure all classes have the permission checked in Account

7 Java security model: privileged regions “Trusted” code can temporarily grant additional privileges to other classes in the call stack Useful in situations where untrusted classes can be allowed to perform specific actions that would otherwise require privileges E.g., an application programmer may decide to  Not give untrusted classes permissions to check balance, credit, or debit an account  Let untrusted classes find out whether the account balance is above or below $1000

8 How privileged regions work class MainClass { public static void main(String [] args) { … MyClass o = new MyClass(); o.m(); } class MyClass { private Account account; … public void debit(int amount) { AccessController.doPrivileged( new PrivilegedAction() { this.account.debit(amount); } public void m() { … RemoteClass obj = new RemoteClass(); obj.giveAccess(MyClass.this)); } MainClass main MyClass m RemoteClass giveAccess Account debit MyClass debit Privileged { } JVM checks that these classes have DebitPermission JVM does not check that these classes have DebitPermission

9 How permissions are defined public class CreditPermission extends BasicPermission {... public boolean implies(Permission p) { return (p instanceof CreditPermission) || (p instanceof FilePermission); }

10 What we would like to verify Often, the developer can easily identify “sensitive” parts of the program Want to verify that these parts are protected by permissions Formally: by the time program point S is reached, permission P has been checked  Have to take into account:  Interprocedural paths  Implication relationships between permissions  “Insecure entry points” --- code that can be called by malicious classes

11 Our approach (high level) Construct a representation of implies relationships among permissions in the program Construct a representation of relationships among sets of permissions Construct a static model of the program  Call graph based Run data flow analysis to determine for each point in the program what permissions must be checked on all paths to that point

12 Permission lattice Define a partial order among permissions based on their implication relationship Because our approach is static, have to place several restrictions on how permissions are defined:  Values of permission parameters have to be statically defined strings  The implies method defined in a way that a permission object implies all permission objects of the same class  Permission objects are immutable Essentially, instead of permission objects, we deal with statically defined permission classes  In practice, such permission definitions are common

13 Permission lattice for the example

14 Permission set lattice To analyze the flow of permissions through the program, need to reason about sets of permissions  Have to define a lattice that describes relationships among sets of permissions, based on the implication relationships Cannot simply say that permission set P 1 implies permission set P 2 if any permission in P 2 is implied by a permission in P 1  Would not be a partial order (e.g. consider sets {p 1 } and {p 1 p 2 }, where p 1 implies p 2 ) Define canonical permission sets  Given a set of permissions, simply remove all permissions that are implied by other permissions in this set

15 Permission set lattice for the example

16 Program representation: Permission Call Graphs (PCGs) Similar to Jensen et al. [IEEE symposium on security and privacy, 1999] and Nitta et al. [ACM symposium on access control models and technologies, 2001] Captures relationships between control flow, permission checking, and privileged regions Each node represents one of  Start of a method execution  Call to a method  checkPermission call  Entrance to a privileged region  Exit from a privileged region Constructed from control flow graphs for all methods in the program Assume that all public methods of public classes can be called by external classes  An overapproximation

17 Permission call graph for the example

18 Data flow algorithm for computing the permission flow Forward-flow all-paths flow-sensitive context- insensitive analysis For each node n in the PCG, differentiate between two sets of paths leading to it:  Paths on which n is executed inside a privileged region  Paths on which n is executed outside privileged regions The algorithm computes two sets of permissions for each node n:  Permissions that are checked on all executions to n where n is executed inside a privileged region: priv(n)  Permissions that are checked on all executions to n where n is executed outside privileged regions: unpriv(n) After a fixed point is reached, a conservative estimate of all permissions checked on all paths to n is the intersection of the two permission sets for n

19 Example of computing priv and unpriv sets for a PCG node checkPermission(DebitPermission) m1m1 m2m2 priv(m 1 ) = {CreditPermission} unpriv(m 1 ) = {CreditPermission} priv(m 2 ) = {DebitPermission} unpriv(m 2 ) = {WritePermission} n IN priv (n) = {WritePermission} IN unpriv (n) = {WritePermission} priv(n) = {WritePermission} unpriv(n) = {DebitPermission}

20 Results of the analysis for the example

21 Checking properties about permissions Given the information from the analysis, can answer questions of the form “is permission p always checked by the time statement s is executed?” Cannot directly answer questions like “is one of permissions p 1, …, p k always checked by the time statement s is executed?”  The algorithm uses the meet operation on the permission set lattice to compute the flow of permissions into a node Can check such properties if the permission lattice is modified  And consequently, the permission set lattice is modified

22 Property-modified lattice for the example The property checks whether one of permissions NewAccountPermission, CreditPermission, DebitPermission is checked on all executions to node 16

23 A violation is detected when checking this property! The analyst can follow the path of permissions through the graph to determine on what type of executions none of permissions NewAccountPermission, CreditPermission, DebitPermission are checked before node 16 is executed It would make sense for CustomerPermission to imply BalancePermission, CreditPermission, and DebitPermission  After the implies method of CustomerPermission is modified accordingly, the analysis successfully proves the property

24 Future work Implementation and experiments  Should scale well, since the analysis is cubic in the size of the PCG and the number of permission types used in the program  Previous approaches (Jensen et al., Nitta et al.) used exponential-time analyses  Believe that in most practical situations, permissions are defined and used in a static fashion  Investigate whether more complex permission- related properties need to be checked The approach is context-insensitive  Do not believe that there is much to be gained by context-sensitivity, but have to check experimentally

25 Questions? I’ll try to answer, but if that fails…  Email: gleb@poly.edu


Download ppt "A Conservative Algorithm for Computing the Flow of Permissions in Java Programs Gleb Naumovich Polytechnic University Brooklyn, USA Presented by David."

Similar presentations


Ads by Google