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