Java Security Model
Download
Report
Transcript Java Security Model
Java Security
Updated May 2007
Topics
Intro to the Java Sandbox
Language Level Security
Run Time Security
Evolution of Security Sandbox Models
The Security Manager
Internet Security Needed
Nowadays, code is downloaded from the
Internet and executed transparently by
millions of users.
Downloaded software can hide all sorts of
hazardous code. Games and music are
often Trojan horses, spyware and virus
installers.
There is a real need for a more security
mechanism for mobile code.
Is This Code Planting a Virus?
http://toilette-humor.com/computer-at-night.html
Writing Secure Code
Software developers also have security
problems to handle. Programmers
unknowingly leave holes in their code
that hackers can exploit.
Forgetting to deallocate resources.
An open socket connection is like an open
invitation to a hacker.
Memory leaks can be exploited
Buffer overflow
The Java Solution
Java Virtual Machine creates a sandbox
Syntax - insecure operations cannot even
be represented
Automatic garbage collection prevents
memory leaks
Security Manager watches for anomalies
during execution and can take action
Interpreters and Compilers
Most languages are either compiled (C, C++,
Pascal) or interpreted (Lisp, Haskell, BASIC).
Source code
object code
MyFile.cpp
compiler
MyFile.exe
MyFile.l
interpreter
JVM
Java is an interpreted language. Your
source code is “compiled” to “bytecode”
which is executed on the JVM (interpreted).
The Java Virtual Machine (JVM) observes
each instruction (bytecode) before it is used.
This allows Java to provide the idea of a
sandbox, which limits how an untrusted
program can affect the system it runs on.
Java and the JVM
The .class file contain Java Bytecode which is
interpreted by the JVM (which is platform specific)
File.java
Compiler
javac
File.class
File.class
Java (JVM)
Language Level Security
No pointers or pointer arithmetic
No way to represent unstructured memory
Variables, methods and classes can be
final
Compiler checks variable instantiation and
typecasts
No Pointers
Pointers and pointer arithmetic allow
attackers to access any byte in memory.
In C, strings and arrays are essentially
unstructured memory. They start with a
pointer and operations on the array are
done by manipulating the pointer. There
is no bounds checking.
The Java programmer cannot represent or
manipulate pointers.
No Pointers
You just can’t write a Java program to do
damage like this.
void main() {
int *randAddress;
randAddress = (int *) rand();
*randAddress = rand();
}
No Unstructured Memory Access
Unstructured memory access (or
unenforced structure) can be exploited.
In C and C++, character data can be
written to memory allocated as integer.
Character or integer data can be read and
interpreted as Boolean.
Java prevents data of one type from being
used as a different type – cannot be
expressed in bytecode.
Source / Bytecode Produced
public float add(float c, int d)
{
return c + d;
}
Method float add(float, int)
fload_1
iload_2
I2f
fadd
freturn
This will fail in Java if d was not an int, but a
program in C assumes d is in the right format
Data Types
All memory and data types include
format info
A 2 byte integer takes up more than
2 bytes in memory – there is
something to indicate that it is an
integer so it can’t be used as
something else.
Unspecified Memory Layout
The JVM stores several types of data to
execute a program
Runtime stacks – one for each thread
Bytecode for methods
Dynamic memory heap and garbage collection
area
The storage layout is not defined for the
JVM. Each implementation does it
differently.
Other Sources of Error
The bytecode instructions for array
operations include bounds checking
Branching instructions can only branch
to instructions in the same method.
Only return and invoke allow
transfer of control outside a given
method.
The Keyword final
This keyword can be used to prevent
variables, methods and classes from being
changed (and potentially exploited).
The value of a variable is fixed for the
duration of the execution.
A method cannot be modified in
subclasses (hacker tactic to use
permission levels of original method)
Class cannot have subclasses (subclass of
API would have full system access).
The Compiler
The compiler checks code and produces
bytecode (intermediate representation
interpreted by all JVMs).
Checks that:
Variables are instantiated before they are used.
Type casts are legal (prevents unstructured
memory exploits)
Methods called by appropriate type objects
Run-time security
Java Virtual Machine – the runtime
environment
Bytecode verifier, class loader, runtime checks
Sandbox evolution
Security manager
Class Loader, Bytecode Verifier
Class loader gets the needed class
Bytecode verifier runs first and guards
against circumvention of compiler checks
with handwritten bytecode.
Class loader checks permissions and helps
to prevent the loading of “Trojan Horse”
methods.
More Checks and Verifications
Version number of compiler
Number and type of parameters passed
to an instruction of method is legal
All bytecode has valid opcodes
No local variable is used before it is
initialized
Symbolic reference check
Run Time Checks
Bounds checking on arrays (no buffer
overflow).
Type cast checking
Automatic garbage collection (memory
leaks can lead to DOS attacks
The Sandbox Idea
The original Java release, jdk1.0, provided
a system that used the basic sandbox
model.
Differentiated only between native code
(code stored locally, trusted, given full
access) and non-native code (applets
downloaded, not trusted).
JDK 1.0 Sandbox
Trusted code can read, write and delete
any file, start and kill threads and open,
use and close socket connections
without any restrictions.
Untrusted code cannot access any files,
threads are hidden and only socket
connections to the applet’s origin server
are allowed.
JDK 1.1: More Flexible
Native code is trusted and treated as in
JDK1.0
Non-native code can be trusted or nontrusted.
If the .jar file has a valid digital signature and
comes from a “trusted developer” (list is part
of the JVM) code is considered trusted and
given same rights as native code.
Otherwise, untrusted and restrictions apply.
JDK 1.2
ALL code (even native) is subject to a
security policy that can be defined by the
user.
Permissions are checked against the policy
when the class is loaded AND whenever
restricted actions are attempted.
Promotes Principle of Least Priviledge
Performs Complete Mediation
JDK 1.2 Restricted Actions
Accept a socket connection
Open a socket connection
Wait for a connection on a port
Create a new process
Modify a thread
Cause the application to exit
Load a dynamic library that contains native methods
Access or modify system properties
Read from a file
Write to a file
Delete a file
Create a new class loader
Load a class from a specified package
Add a new class to a specified package
The Security Manager
The part of the JVM that performs these
run time checks is called the security
manager
JDK 1.2 or later (a.k.a. Access Manager)
In addition the security manager watches
other potential security holes and can react
if needed.
Possible Problems
Security features not automatic if Java
program is invoked on the command line
And others as yet undiscovered …
Readings
http://java.sun.com/sfaq
http://www.javaworld.com/javaworld/jw-08-1997/jw-08-hood_p.html