You are on page 1of 62

From Stack Inspection

to Access Control
Mechanism
Professor: Dr. Centonze
Lecture N.3, N.4 Notes
Fall 2015
Reference Book
Lecture Outlines
 From stack Inspection mechanism to access control:
 JVM (Java Virtual Machine)
 CLR (Common Language Runtime)

 Java 2 Security Architecture and Programming


 Example of Java 2 policy inspection permission
 Combining static and dynamic permission analysis to
enforce the security principle (the Principle of Least
Privilege)
 Example of SBAC (Stack Based Access Control)
The Principle of Least
Privilege
 In a computing environment, every module (such as a
process, a user, or a program) must be able to access
only such information and resources that are
necessary to its legitimate purpose [Saltzer and
Shroeder, 1975]
 Example:
 Grant a text editor the permission to access the file
system
 Do not grant a text editor the permission to open a
socket connection (read more about socket connection
at this URL:
http://journals.ecs.soton.ac.uk/java/tutorial/networking/s
ockets/definition.html)
4
Problems in Enforcing the
Principle of Least Privilege
 An authorization policy must be neither too permissive nor too
restrictive
 Too permissive (false positives with static analysis):
 Violation of the Principle of Least Privilege
User
 Program exposed to security attacks
 Too restrictive (false negatives with dynamic analysis):
 The policy-enforcement mechanism will generate run-
time authorization failures
 Security problems may arise (why?) Program
 Automatic determination of:
 Precise set R of permissions requested by code and users
at any given program point
 Evaluation and consistency policies
 Validate that the set of permissions granted (G) to
an application is never grater than the set of G R
permissions requested (R) by the application
 Applicability to real word solutions
Access Rights
(Permissions Sets)
5
Stack Inspection
 Modern, networked systems are component-based
(.NET, J2EE, CLR, Java, etc…)
 Components (e.g. in Java are jar files) may have
different origins and may call each other
 Stack inspection is a security technique to ensure that all
components on a call stack have been granted the
requested permission
 Before accessing a sensitive resource (a file, socket,
etc.), the call stack is inspected to verify that every caller
has been granted the requested permission
Two Stack Inspection
Systems
JVM Common Language Runtime (CLR)

C#, Visual Basic,


Java Program
Program

Compiler Compiler

Bytecode IL

JVM CLR

OS (Windows, Microsoft
Linux, MAC, …) Windows
Access Control Decisions
 A permission is the right to access a protected resource
 Permissions are granted to:
 Code
 Users

 Permissions granted to code are based on:


 The URL location from which the code is coming
 The signers of the code

 Permissions granted to users are based on:


 The authentication information of the users
Stack-Based Access
Control
JVM CLR

p,q p,q

p,q p,q

p,q p,q

p,q p,q

p q p q

p q p q

Access Access demand(p) demand(q)


Controller. Controller.
check check x Permission x must have been granted
Permission(p) Permission(q)
Privileged Code
JVM CLR

} {
Permissions p and q
Permissions p and q are checked, but
q
are not checked, assert(p) adds p,
so they are both while q must have
implicitly granted been explicitly granted q

p,q The stack walk stops here The stack walk does not stop here p,q

AccessController.
p,q doPrivileged()
assert(p) p q

p q p q

demand(p) demand(q)
p q

Access Access
Controller. Controller.
check check x Permission x must have been granted
Permission(p) Permission(q)
Static and Dynamic Analysis
1. Manual code inspection
 Pros:
 Only reasonable for small programs
 Cons:
 Tedious
 Time consuming
 Error prone

2. Dynamic analysis
 Pros:
 Complete (no false positives)
 Cons:
 Unsound (false negatives)
 Need for test cases
 Need for configuration
 Unsafe (program under analysis can compromise the integrity or confidentiality of the system)

3. Static analysis
 Pros:
 Theoretically sound (no false negatives if it models native methods, reflection, and callbacks)
 No need for test cases
 No need for configuration
 Safe
 Cons:
 Unsound in practice (false negatives if there is no model of native methods, reflection and callbacks)
 Conservative (false positives)
Permission Configuration
Complexity
 Given a large program or library, it is very difficult to identify what
permissions the program requires
 Manual code inspection
 Time consuming and error prone
 Source code not always available Fred Schneider’s
 Static analysis Approach:
 Potentially conservative
 Potentially unsound (native methods, reflection) Run program
 May take a long time to analyze even small applications
 May not scale to large applications Inspect Exception
 Dynamic analysis
 Non conservative Identify JAR
 Potentially unsound
 Requires writing test cases Grant/deny permission
 Time consuming
Access Control Explorer For Java
(ACE4J) for Dynamic Permissions

FilePermission "log.txt", "write"


FilePermission "config.txt", "read"
SocketPermission "ibm.com", "connect"
RuntimePermission "createClassLoader"
PropertyPermission "java.version","read"

Program Components Authorization Analysis Access-Control Policy


14

Java Security
Stack Based Access Control (SBAC)
Table of Contents
I. Brief overview of the three Legs of Java Security
 The Class Loading System
 The Class File Verifier
 The Security Manager

II. The Java 2 Access-Control Model

III. Example of SBAC

15
Part I – The Three Legs of
Java Security

16
The First Leg – The Class
Loading System

 Name space separation and isolation

 Core Java packages boundary protection

 Permission assignment

17
Why You Need to Know
about Class Loaders
 If you are an application developer, you can take
advantage of the security features of the class loading
system
 If you are a JVM or container developer, you need to
know how to develop a secure class loader

18
Class Isolation
 Classes loaded by class loaders in
different branches of the tree are
isolated:
They cannot directly reference each
Primordial other
Direct cross name visibility is forbidden
Extension
 Classes loaded from different remote
locations are isolated
Application

Custom A Custom C

Custom B Custom D

Custom E Custom F

19
Core Java Packages
Boundary Protection
 When a Java class is being loaded, and the class
declares to belong to a trusted package (see
example below), the class loader asks the security
manager to check whether or not the code is
authorized to define a class in that package
 This protects core packages from malicious code

java.lang.MaliciousClass
java.lang package
The Second Leg – The Class
File Verifier
 It is an integral part of the JVM, written in native code
(e.g. low level language)
 It makes sure that loaded classes cannot:
 Contain illegal byte-code instructions
 Forge pointers to protected memory
 Over/underflow the program stack
 Corrupt the JVM integrity

 It is there to prevent:
 Java-compiler and Java byte-code attacks
 Non-Java-compiler attacks

21
Native Code Definition
Java-Compiler and
Java-Byte-code Attacks
 All valid Java source code programs can be
compiled to byte-code programs
Java source code A certified Java compiler only generates
legal byte-code
A malicious Java compiler may generate
Java compiler programs attempting to subvert (ruin) the
integrity of the JVM
Java byte-code
 There are byte-code programs that have no
corresponding Java source
JVM It is possible to generate Java byte-code
programs from other high-level languages
(such as NetRexx, COBOL)
Machine code
It is possible to edit the byte-code

23
The Third Leg – The
Security Manager
 Enforces access-control restrictions
 It is an instance of java.lang.SecurityManager or one of its
subclasses
 The default security manager is java.lang.SecurityManager
 Application developers can subclass the default security manager

 By default, applications run without a security manager


 A security manager can be enforced:
 Statically, with the –Djava.security.manager command-line flag
 Programmatically, by creating a new SecurityManager instance and passing it to
java.lang.System.setSecurityManager()
 java.lang.RuntimePermission “createSecurityManager”
 java.lang.RuntimePermission “setSecurityManager”

 There cannot be more than one security manager in effect at any time
 The current security manager can be retrieved by calling
System.getSecurityManager()
Types of Attack
 Attacks prevented by the default security manager:
 System-modification attacks
 A program gets write access and makes changes to the system
 Privacy-invasion attacks
 A program gets read access and steals private information

 Attacks the default security manager does not currently prevent:


 Denial of service attacks
 A program inappropriately uses system resources without authorization (CPU,
AWT windows, etc.)
CPU Usage

CPU

Time
Security Manager’s Areas
of Control
 The Security Manager class offers a number of check
methods to enforce access control
 checkRead(), checkWrite(), checkConnect(), etc.

 Each check method instantiates a


java.security.Permission object representing the
type of access being attempted and passes it to
checkPermission()

Network Thread File system Operating system JVM Packages and classes Security
Operation of the
SecurityManager
Main.main()

FileOutputStream.<init>(logFileName)

sm= instance of SecurityManager sm.checkWrite(logFileName)

return SecurityException

27
SecurityManager
Extensions
 SecurityManager can be sub-classed to:
 Keep track of requests for access to certain
resources
 Prompt the user with user ID and password
before granting access to a particular
resource
 Prevent access to certain resources even if
someone explicitly grants permission

28
Example – Overriding
checkWrite()
public void checkWrite(String filename) {
String pwd;
System.out.println("What's the secret password for writing the file?");
try {
pwd = new BufferedReader(new
InputStreamReader(System.in)).readLine();
if (! pwdgiven.equals(pwd))
throw new SecurityException("Permission denied – Wrong password");
}
catch (IOException e) {
throw new SecurityException("Permission denied – Password
problems");
}
// Uncomment the line below if you want to call
// SecurityManager.checkWrite() in the superclass at this time

// super.checkWrite(filename);
}

29
Example – Overriding
checkPermission()
public void checkPermission(Permission perm)
{
if (perm instanceof RuntimePermission && perm.getName() == "queuePrintJob")
{
throw new SecurityException();
}
else
super.checkPermission(perm);
}

30
Interdependence of the
Three Java Security Legs
 The security manager relies on the class loading system
 To keep name spaces separated
 To associate permissions with each loaded class
 To prevent system classes from being replaced

 The class loading system relies on the security manager


 To prevent untrusted code from instantiating new ClassLoader
objects
 To prevent trusted system packages from being extended

 Both the class loading system and the security manager rely
on the class file verifier
 To prevent malformed byte-code attacks

31
Part II – The Java 2 Access-
Control Model

32
The Basic Idea
 Java 2 offers a fine-grained access-control model

 By default, the security manager denies access to all protected system


resources
 It is possible to specify in detail what code is allowed to do based on:
1. The URL location from which the code is coming
2. The signers of the code
 Multiple signers are allowed
 The JVM verifies signatures transparently
3. The identity of the user running the code (with JAAS)

 Permissions are granted declaratively in a policy database (e.g. text


file)

33
The Concept of Permission
in Java 2
 A permission is the right to access a protected resource

 The Java 2 platform offers the abstract


java.security.Permission class to represent permissions
o Each permission is represented as an object of a subclass of
Permission
o Standard Permission classes are provided to represent the right to
access protected system resources

 In Java, permissions are positive

Network Thread File system Operating system JVM Packages and classes Security
The Permission Class
Hierarchy
Permission

FilePermission

AllPermission
SocketPermission

BasicPermission

AWTPermission PropertyPermission

RuntimePermission SecurityPermission
Location of the Permission
Classes
 Permission classes are part of the package where
they are most likely to be used:
 FilePermission in package java.io
 SocketPermission in package java.net
 SecurityPermission in package
java.security

36
Permission Target and
Action
 A Permission object may have a target and an optional
list of actions
 The target is the object of the permission
 The action is the type of access being attempted

Permission Target Action


FilePermission File or directory name read
write
execute
delete
SocketPermission Host name resolve
accept
connect
listen
PropertyPermission Property name read
write
The Permission implies( )
method
 The Permission class has an abstract instance method, implies()

 implies() takes a Permission object parameter and returns a


boolean
 Given p and q Permission objects
 If p.implies(q) returns true, then p is stronger or equivalent to q (granting
p implicitly grants q too)
 p = new FilePermission("C:/tmp/*", "read");
 q = new FilePermission("C:/tmp/file.txt", "read");
 If p.implies(q) returns false, then p is not stronger or equivalent to q, but
this does not necessarily mean that q is stronger than p
 p = new FilePermission("C:/tmp/*", "read");
 q = new SocketPermission("www.ibm.com", "80");

38
Dangerous Permissions
 java.security.AllPermission
 Implies all the other Permissions!
 Automatically granted to system code (classes in the boot class path)

 java.lang.RuntimePermission “createSecurityManager” and


java.lang.RuntimePermission “setSecurityManager”
 Replacing the SecurityManager gives full system control

 java.lang.RuntimePermission “createClassLoader”
 A new ClassLoader instance could load malicious code that can:
 Bypasses all the class file verifier checks
 Replaces system classes or invades system packages
 Is granted AllPermission

 java.lang.RuntimePermission “loadLibrary.*”
 Native code is not subjected to any Java security restrictions!
Security Policy
 Permissions are granted to code declaratively in a policy database (e.g. text file)
 The J2SE reference implementation comes with a flat-file-based policy database,
called the policy file
 Editable with a text editor or with the Policy Tool (policytool)
 Policy providers can supply more sophisticated implementations by subclassing the
abstract class java.security.Policy

 There can be multiple policy files in effect at any time, listed in the
${java.home}/jre/lib/security/java.security configuration file:
 A user-defined policy file, ${user.home}/.java.policy
 A system-wide policy file, ${java.home}/jre/lib/security/java.policy
 A corporate-wide policy file, retrievable remotely

 There is only one Policy object in effect at any given time


 Policy files are portable across different platforms
 Variables ${java.home}, ${user.home}, ${file.separator}, etc. are resolved at runtime based
on the underlying platform
1. Example of Policy File
grant Entry
grant signedBy "ibm, tivoli", codeBase "http://www.ibm.com" {
permission java.net.SocketPermission "www.ibm.com:80", "connect";
permission java.io.FilePermission "C:/log.txt", "write";
};

Signed by URL location

http://www.ibm.com
AND

41
2. Example of Policy File
grant Entry
grant signedBy "ibm", codeBase "http://www.ibm.com" {
permission java.net.SocketPermission "www.ibm.com:80", "connect";
permission java.io.FilePermission "C:/log.txt", "write";
};
grant signedBy "tivoli", codeBase "http://www.ibm.com" {
permission java.net.SocketPermission "www.ibm.com:80", "connect";
permission java.io.FilePermission "C:/log.txt", ”read";
};

Signed by URL location

http://www.ibm.com
OR

42
3. Example of Policy File
Grant Entry
Code Source and
Protection Domain
grant signedBy "ibm, tivoli", codeBase "http://www.ibm.com" {
permission java.net.SocketPermission "www.ibm.com:80", "connect";
permission java.io.FilePermission "C:/log.txt", "write";
};

Cert 1
Cert 2 URL
… Permission
Class Cert n

CodeSource PermissionCollection

ProtectionDomain
JVM

44
Sign Java and Java Applets
Code Applications
 http://docs.oracle.com/javase/7/docs/technotes/guid
es/jweb/security/
rsa_signing.html
 More reference and links are provided also on
Blackboard
 http://people.cs.uchicago.edu/~stefanko/Teaching/C
S102-Sum2001/Applets/
Applets.html
Security Considerations
 A protection domain encapsulates a code source (codebase) and a
permission collection, but it is a function of the code source only
 Classes with the same code source have:
1. the same permissions
2. and automatically belong to the same protection domain
 Classes with the same permissions:
 may not belong to the same protection domain

 ClassLoader instances are designed to associate a protection domain


with each loaded class
 The protection domain of the core system classes is called the system
domain
 The protection domain of an application is called an application domain
 There are as many application domains as the number of code sources
The Design
 The Java 2 access-control model is designed to
prevent untrusted code from gaining the privileges
of more trusted code it may interact with

Application System
code class

Untrusted, Fully trusted,


No permissions AllPermission

Application System
code class

Untrusted, Fully trusted,


No permissions47 AllPermission
Example – Code Requiring
Permissions
import java.net.*;
import java.io.*;

public class Main {


public static void main(String[] args)
throws UnknownHostException, IOException {
Socket socket = new Socket("www.ibm.com", 80);
}
}

java -Djava.security.manager javaclassname

48
How the Java 2 Access-
Control Model Works
If Main’s code source was
granted Permission p…
Main.main() p ?
Otherwise…
SecurityException
Socket.<init>("www.ibm.com", 80) p ?
sm = System.getSecurityManager(); sm.checkConnect("www.ibm.com", 80) p ?
p = new SocketPermission
("www.ibm.com:80", "connect"); sm.checkPermission(p) p
?
AccessController.checkPermission(p) p ?
The Need for Privileged
Code
 Library code may need to perform security-sensitive operations that technically the
client did not request
 (e.g., logging certain events to a file, getting the font files, etc.)

 Based on the last java example (previous slide)


 The client code (usually the main class) will not work unless it is granted the additional
permission
 This violates the Principle of Least Privilege

Client SocketPermission Library SocketPermission


code FilePermission code

FilePermission

50
Example without
Privileged Code – 1
import java.io.*;
import java.net.*;
library code
public class LibraryCode {
private static String logFileName = "log.txt";
public static Socket createSocket(String host, int port)
throws UnknownHostException, IOException {
Socket socket = new Socket(host, port);
FileOutputStream fos = new FileOutputStream(logFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
PrintStream ps = new PrintStream(bos, true);
ps.print("Created socket " + host + ":" + port);
return socket;
}
}

public class Main {


public static void main(String[] args) throws NumberFormatException,
UnknownHostException, IOException {
String host = args[0];
int port = new Integer(args[1]).intValue();
createSocket(host, port, debug);
}
51 client code
Example without
Privileged Code – 2
Main.main() p,q

LibraryCode.createSocket() p,q

Socket.<init>(host, port) q FileOutputStream.<init>(logFileName) p

sm.checkConnect(host, port) q sm.checkWrite(logFileName) p

sm.checkPermission(q) q sm.checkPermission(p) p

AccessController.checkPermission(q) q AccessController.checkPermission(p) p

If Main’s code source was


granted both p and q…

Permission p is checked
p Otherwise…
p = new FilePermission(logFileName, "write");
SecurityException

q
Permission q is checked
q = new SocketPermission(host, port);
52
Privileged Code in Java 2
 The portion of code that should be made privileged must be
wrapped into the run() method of a:
 java.security.PrivilegedAction subclass if the code
does not throw a checked exception (one listed in a throws
clause)
 java.security.PrivilegedExceptionAction subclass
if the code does throw a checked exception

 The run() method returns an Object

 An object of type PrivlegedAction or


PrivilegedExceptionAction must be passed to
AccessController.doPrivileged(), which returns
the run() method’s return value

53
Privileged Code Security
Considerations
 AccessController.checkPermission()
stops the permission checking at the method calling
doPrivileged()
 The code above it (doPrivileged())in the stack
is exempted from those permission requirements
(but not from other permission requirements)

54
Example with Privileged
Code – 1
import java.io.*;
import java.net.*;
import java.security.*;

public class LibraryCode2 {


private static String logFileName = "log.txt";

public static Socket createSocket(String host, int port)


throws UnknownHostException, IOException, PrivilegedActionException {
Socket socket = new Socket(host, port);
PrivilegedOp op = new PrivilegedOp(host, port, logFileName);
AccessController.doPrivileged(op);
return socket;
}
}

55
Example with Privileged
Code – 2
class PrivilegedOp implements PrivilegedExceptionAction {
String host, logFileName;
int port;

PrivilegedOp(String host, int port, String logFileName) {


this.host = host;
this.port = port;
this.logFileName = logFileName;
}

public Object run() throws IOException {


File of = new File(logFileName);
FileOutputStream os = new FileOutputStream(of);
BufferedOutputStream bos = new BufferedOutputStream(os);
PrintStream ps = new PrintStream(bos, true);
ps.print("Created socket " + host + ":" + port);
return null;
}
}

56
Example with Privileged
Code – 3
Main.main() q
Permission checking
LibraryCode2.createSocket() p,q
for p stops here

Socket.<init>(host, port) q AccessController.doPrivileged(op) p

sm.checkConnect(host, port) q op.run() p

sm.checkPermission(q) q FileOutputStream.<init>(logFileName) p

AccessController.checkPermission(q) q sm.checkWrite(logFileName) p

If Main’s code source was sm.checkPermission(p) p

granted permission q…
AccessController.checkPermission(p) p

Permission p is checked
p Otherwise…
p = new FilePermission(logFileName,
SecurityException "write");
Main’s code source does
q
Permission q is checked not need permission p!
q = new SocketPermission(host, port);
57
Example with Privileged
Code – 3
Main.main() q
Permission checking
LibraryCode2.createSocket() p,q
for p stops here

Socket.<init>(host, port) q AccessController.doPrivileged(op) p

sm.checkConnect(host, port) q op.run() p

sm.checkPermission(q) q FileOutputStream.<init>(logFileName) p

AccessController.checkPermission(q) q sm.checkWrite(logFileName) p

sm.checkPermission(p) p

 Challenges Problems: AccessController.checkPermission(p) p


 What portions of library code
should be made privilege-
asserting?
 What permissions are implicitly
extended to client code?
58
Lab Homework
1. Try to separate the LibraryCode.java sample into two java classes:
a. Main.java
b. LibraryCode.java

2. Then, created two jar files:


a. Main.jar
b. LibraryCode.jar

3. Try to run the Main.jar from a command line without activating the security.manager and using LibraryCode.jar
in the class path (look at the hand-out that I gave you in class on how to do this)

4. Once that is running try to chance your java.policy file by creating two different codebases (like my example on
slide n. 61)

5. Then from a command line now run the Main.jar which uses the LibraryCode.jar in the class path This time
activate the security.manager and point to your java.policy file that you have just changed.

6. What do you get when you running and why?

7. Once you have all done the above steps, try to change the LibraryCode.java by adding the java code for the
privilege code and by adding the PrivilledgeOp.java (like my slides n.55, 56 ) create another LibraryCode.jar with
the updated privileged code.

8. Then try to run the Main.jar as you did before in step 5 above. What do you get now and why?
Changing The Policy File
When doPriviledge() is
Implemented
 Need to add two jars files:
 1) The jar containing the Main.java (client code)
 2) The jar containing the LibraryCode.java (librarycode)

 In the the java.policy file you have to define two different codebase
with specific permissions:
 Main.java  Main.jar (SocketPermission, connect, resolve)
 LibraryCode.java  LibraryCode.jar (SocketPermission,
FilePermission)
Example of Policy File
when doPrivileged() is
implemented

//Main.jar” {

}};
Related Research Paper
 Centonze at al., Access-rights Analysis in the Presence of Subjects.
ECOOP 2015, Prague, Czech Republic
 http://2015.ecoop.org/event/research-track-access-rights-analysis-in-
the-presence-of-subjects

 Download and read the paper (graduate students): http


://drops.dagstuhl.de/opus/volltexte/2015/5224/pdf/14.pdf
 Centonze at al. Combining Static and Dynamic Analysis for
Automatic Identification of Precise Access-Control Policies. ACSAC
2007. Miami Beach Resort & Spa, Miami Beach, Florida, USA.
 Graduate students read and present this paperhttps
://www.acsac.org/2007/papers/175.pdf (one or two students
volunteer to present to the whole class ~ 30 minutes)

You might also like