Java Security

advertisement
Current Techniques in
Language-based Security
David Walker
COS 597B
With slides stolen from:
Steve Zdancewic
University of Pennsylvania
Mobile Code
 Modern languages like Java and C# have
been designed for Internet applications and
extensible systems
applet
applet
applet
web browser
operating system
 PDAs, Cell Phones, Smart Cards, …
COS 597B
2
Applet Security Problems
 Protect OS & other valuable resources.
 Applets should not:
 crash browser or OS
 execute “rm –rf /”
 be able to exhaust resources
 Applets should:
 be able to access some system resources (e.g. to
display a picture)
 be isolated from each other
 Principles of least privileges and complete
mediation apply
COS 597B
3
Java and C# Security
 Static Type Systems
 Memory safety and jump safety
 Run-time checks for
 Array index bounds
 Downcasts
 Access controls
These
lectures
 Virtual Machine / JIT compilation
 Bytecode verification
 Enforces encapsulation boundaries (e.g. private field)
 Garbage Collected
 Eliminates memory management errors
 Library support
 Cryptography, authentication, …
COS 597B
4
Access Control for Applets
 What level of granularity?
 Applets can touch some parts of the file system but not
others
 Applets can make network connections to some locations
but not others
 Different code has different levels of trustworthiness
 www.l33t-hax0rs.com vs. www.java.sun.com
 Trusted code can call untrusted code
 e.g. to ask an applet to repaint its window
 Untrusted code can call trusted code
 e.g. the paint routine may load a font
 How is the access control policy specified?
COS 597B
5
Outline
 Java Security Model
(C# similar)
 Stack inspection
 Concrete examples
 To discuss: what security principles does the Java
security model obey or not obey?
 Semantics from a PL perspective
 Formalizing stack inspection
 Reasoning about programs that use stack
inspection
COS 597B
6
Java Security Model
VM Runtime
a.class
b.class
c.class
d.class
e.class
Security Policy
Domain A
Permissions
Domain B
Permissions
Classloader
SecurityManager
http://java.sun.com/j2se/1.4.2/docs/guide/security/spec/security-specTOC.fm.html
COS 597B
7
Kinds of Permissions
 java.security.Permission Class
perm = new java.io.FilePermission("/tmp/abc","read");
java.security.AllPermission
java.security.SecurityPermission
java.security.UnresolvedPermission
java.awt.AWTPermission
java.io.FilePermission
java.io.SerializablePermission
java.lang.reflect.ReflectPermission
java.lang.RuntimePermission
java.net.NetPermission
java.net.SocketPermission
…
COS 597B
8
Code Trustworthiness
 How does one decide what protection domain
the code is in?
 Source (e.g. local or applet)
 Digital signatures
 C# calls this “evidence based”
 How does one decide what permissions a
protection domain has?
 Configurable – administrator file or command line
 Enforced by the classloader
COS 597B
9
Classloaders
 In order to pull new code into the virtual machine, we
use an object from the ClassLoader class
 A class loader will look in the file system, or across
the network for a class file, or possibly dynamically
generate the class
 When loading the first class of an application, a new
instance of the URLClassLoader is used.
 When loading the first class of an applet, a new instance of
the AppletClassLoader is used.
 Class loaders are responsible for placing classes into
their security domains
 AppletClassLoader places classes in domains depending on
where they are from
 Other ClassLoaders places classes in domains based on
digital signatures, or origin (such as local file system)
COS 597B
10
Associating Privileges with Domains
grant codeBase “http://www.l33t-hax0rz.com/*” {
permission java.io.FilePermission(“/tmp/*”, “read,write”);
}
grant codeBase “file://$JAVA_HOME/lib/ext/*” {
permission java.security.AllPermission;
}
grant signedBy “trusted-company.com” {
permission java.net.SocketPermission(…);
permission java.io.FilePermission(“/tmp/*”, “read,write”);
…
}
Policy information stored in:
$JAVA_HOME/lib/security/java.policy
$USER_HOME/.java.policy
(or passed on command line)
COS 597B
12
Example Trusted Code
Code in the System protection domain
void fileWrite(String filename, String s) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
FilePermission fp = new FilePermission(filename,“write”);
sm.checkPermission(fp);
/* … write s to file filename (native code) … */
} else {
throw new SecurityException();
}
}
public static void main(…) {
SecurityManager sm = System.getSecurityManager();
FilePermission fp = new FilePermission(“/tmp/*”,“write,…”);
sm.enablePrivilege(fp);
UntrustedApplet.run();
}
COS 597B
13
Example Client
Applet code obtained from
http://www.l33t-hax0rz.com/
class UntrustedApplet {
void run() {
...
s.FileWrite(“/tmp/foo.txt”, “Hello!”);
...
s.FileWrite(“/home/stevez/important.tex”, “kwijibo”);
...
}
}
COS 597B
14
Stack Inspection
 Stack frames are annotated with their
protection domains and any enabled
privileges.
 During inspection, stack frames are searched
from most to least recent:
 fail if a frame belonging to someone not
authorized for privilege is encountered
 succeed if activated privilege is found in frame
COS 597B
15
Stack Inspection Example
fp = new FilePermission(“/tmp/*”,“write,…”);
Policy Database
main(…){
sm.enablePrivilege(fp);
UntrustedApplet.run();
}
COS 597B
16
Stack Inspection Example
Policy Database
main(…){
fp = new FilePermission(“/tmp/*”,“write,…”);
sm.enablePrivilege(fp);
UntrustedApplet.run();
fp
}
COS 597B
17
Stack Inspection Example
Policy Database
void run() {
…
s.FileWrite(“/tmp/foo.txt”, “Hello!”);
…
}
main(…){
fp = new FilePermission(“/tmp/*”,“write,…”);
sm.enablePrivilege(fp);
UntrustedApplet.run();
fp
}
COS 597B
18
Stack Inspection Example
void fileWrite(“/tmp/foo.txt”, “Hello!”) {
fp = new FilePermission(“/tmp/foo.txt”,“write”)
sm.checkPermission(fp);
/* … write s to file filename … */
Policy Database
void run() {
…
s.FileWrite(“/tmp/foo.txt”, “Hello!”);
…
}
main(…){
fp = new FilePermission(“/tmp/*”,“write,…”);
sm.enablePrivilege(fp);
UntrustedApplet.run();
fp
}
COS 597B
19
Stack Inspection Example
void fileWrite(“/tmp/foo.txt”, “Hello!”) {
fp = new FilePermission(“/tmp/foo.txt”,“write”)
sm.checkPermission(fp);
/* … write s to file filename … */
main(…){
fp = new FilePermission(“/tmp/*”,“write,…”);
Policy Database
void run() {
…
s.FileWrite(“/tmp/foo.txt”, “Hello!”);
…
}
Succeed!
fp
sm.enablePrivilege(fp);
UntrustedApplet.run();
}
COS 597B
20
Stack Inspection Example
Policy Database
void run() {
…
s.FileWrite(“/home/stevez/important.tex”,
“kwijibo”);
}
main(…){
fp = new FilePermission(“/tmp/*”,“write,…”);
sm.enablePrivilege(fp);
UntrustedApplet.run();
fp
}
COS 597B
21
Stack Inspection Example
void fileWrite(“…/important.txt”, “kwijibo”) {
fp = new FilePermission(“important.txt”,
“write”);
sm.checkPermission(fp);
Fail
main(…){
fp = new FilePermission(“/tmp/*”,“write,…”);
sm.enablePrivilege(fp);
UntrustedApplet.run();
Policy Database
void run() {
…
s.FileWrite(“/home/stevez/important.tex”,
“kwijibo”);
}
fp
}
COS 597B
22
Other Possibilities
 The fileWrite method could enable the
write permission itself
 Potentially dangerous, should not base the file to
write on data from the applet
 … but no enforcement in Java (information flow
would help here)
 A trusted piece of code could disable a
previously granted permission
 Terminate the stack inspection early
COS 597B
23
Stack Inspection Algorithm
checkPermission(T) {
// loop newest to oldest stack frame
foreach stackFrame {
if (local policy forbids access to T by class executing in
stack frame) throw ForbiddenException;
if (stackFrame has enabled privilege for T)
return; // allow access
if (stackFrame has disabled privilege for T)
throw ForbiddenException;
}
// end of stack
if (Netscape || …) throw ForbiddenException;
if (MS IE4.0 || JDK 1.2 || …) return;
}
COS 597B
24
Two Implementations
 On demand –
 On a checkPermission invocation, actually crawl
down the stack, checking on the way
 Used in practice
 Eagerly –
 Keep track of the current set of available
permissions during execution (security-passing
style Wallach & Felten)
+ more apparent (could print current perms.)
- more expensive (checkPermission occurs
infrequently)
COS 597B
25
Stack Inspection
 Stack inspection seems appealing:
 Fine grained, flexible, configurable policies
 Distinguishes between code of varying degrees of trust
 But…
 How do we understand what the policy is?
 Semantics tied to the operational behavior of the program
(defined in terms of stacks!)
 How do we compare implementations
 Changing the program (e.g. optimizing it) may change the
security policy
 Policy is distributed throughout the software, and is not
apparent from the program interfaces.
 Is it any good?
COS 597B
26
Stack Inspection Literature
 Stack Inspection: Theory and Variants
Cédric Fournet and Andrew D. Gordon
 Understanding Java Stack Inspection
Dan S. Wallach and Edward W. Felten
 Formalize Java Stack Inspection using ABLP logic
 And many more...
COS 597B
27
Formalizing Stack Inspection
Abstract Stack Inspection
 Abstract permissions
 p,q
 R,S
Permissions
Principals (sets of permissions)
 Hide the details of classloading, etc.
 Examples:
System = {fileWrite(“f1”), fileWrite(“f2”),…}
Applet = {fileWrite(“f1”)}
COS 597B
29
lsec Syntax
 Language syntax:
e,f ::=
x
lx.e
e f
R{e}
enable p in e
test p then e else f
fail
v ::= x
o ::= v
|
|
lx.e
fail
expressions
variable
function
application
framed expr
enable
check perm.
failure
values
outcome
COS 597B
30
Framing a Term
 Models the Classloader that marks the
(unframed) code with its protection domain:
R[x]
= x
R[lx.e] = lx.R{R[e]}
R[e f] = R[e] R[f]
R[enable p in e] = enable p in R[e]
R[test p then e else f] =
test p then R[e] else R[f]
R[fail] = fail
COS 597B
31
Example
readFile =
lfileName.System{
test fileWrite(fileName) then
… // primitive file IO (native code)
else fail
}
Applet{readFile “f2”}  fail
System{readFile “f2”}  <f2 contents>
COS 597B
32
lsec Operational Semantics
 Evaluation contexts:
E ::=
[]
E e
v E
enable p in E
R{E}
Hole
Eval. Function
Eval. Arg.
Tagged frame
Frame
 E models the control stack
COS 597B
33
lsec Operational Semantics
E[(lx.e) v]
E[enable p in v]
E[R{v}]
E[fail]
E[test p then e else f]





E[e{v/x}]
E[v]
E[v]
fail
E[e]
if Stack(E) |-- p
E[test p then e else f]  E[f]
if (Stack(E) |-- p)
eo
iff
e * o
COS 597B
Stack
Inspection
34
Example Evaluation Context
Applet{readFile “f2”}
E = Applet{[]}
r = readfile “f2”
COS 597B
35
Example Evaluation Context
Applet{readFile “f2”}
E = Applet{[]}
r = (lfileName.System{
test fileWrite(fileName) then
… // primitive file IO (native code)
else fail
})
“f2”
COS 597B
36
Example Evaluation Context
Applet{readFile “f2”}
E = Applet{[]}
r = System{
test fileWrite(“f2”) then
… // primitive file IO (native code)
else fail
}
COS 597B
37
Example Evaluation Context
Applet{System{
test fileWrite(“f2”) then
… // primitive file IO (native code)
else fail
}}
COS 597B
38
Example Evaluation Context
Applet{System{
test fileWrite(“f2”) then
… // primitive file IO (native code)
else fail
}}
E’ = Applet{System{[]}}
r’ = test fileWrite(“f2”) then
… // primitive file IO (native code)
else fail
COS 597B
39
Formal Stack Inspection
E’ = Applet{System{[]}}
r’ = test fileWrite(“f2”) then
… // primitive file IO (native code)
else fail
When does stack E’ allow permission
fileWrite(“f2”)?
Stack(E’) |-- fileWrite(“f2”)
COS 597B
40
Stack of an Eval. Context
Stack([])
= .
Stack(E e)
= Stack(E)
Stack(v E)
= Stack(E)
Stack(enable p in E) = enable(p).Stack(E)
Stack(R{E})
= R.Stack(E)
Stack(E’)
= Stack(Applet{System{[]}})
= Applet.Stack(System{[]})
= Applet.System.Stack([])
= Applet.System.
COS 597B
41
Abstract Stack Inspection
. |-- p
empty stack axiom
x |-- p p  R
x.R |-- p
protection domain check
x |-- p
x.enable(q) |-- p
p  q irrelevant enable
x |= p
x.enable(p) |-- p
check enable
COS 597B
42
Abstract Stack Inspection
. |= p
pR
x.R |= p
x |= p
x.enable(q) |= p
empty stack enables all
enable succeeds*
irrelevant enable
* Enables should occur only in trusted code
COS 597B
43
Equational Reasoning
e iff there exists o such that e  o
Let C[] be an arbitrary program context.
Say that e = e’ iff
for all C[], if C[e] and C[e’] are closed then
C[e] iff C[e’].
COS 597B
44
Example Inequality
let x = e in e’ = (lx.e’) e
ok = lx.x
loop = (lx.x x)(lx.x x)
(note: loop )
f = lx. let z = x ok in l_.z
g = lx. let z = x ok in l_.(x ok)
Claim: f ≠ g
Proof:
Let C[] = {[] l_.test p then loop else ok} ok
COS 597B
45
Example Continued
C[f] = {f l_.test p then loop else ok} ok
•
 {let z =
(l_.test p then loop else ok) ok
in l_.z} ok
•
 {let z = test p then loop else ok
in l_.z} ok
•
 {let z = ok in l_.z} ok
•
 {l_.ok} ok
•
 (l_.ok) ok
•
 ok
COS 597B
46
Example Continued
C[g] = {g l_.test p then loop else ok} ok
•
 {let z =
(l_.test p then loop else ok) ok
in l_.((l_.test p then loop else ok) ok)} ok
•
 {let z = test p then loop else ok
in l_. ((l_.test p then loop else ok) ok)} ok
•
 {let z = ok
in l_. ((l_.test p then loop else ok) ok)} ok
•
 {l_. ((l_.test p then loop else ok) ok)} ok
•
 (l_. ((l_.test p then loop else ok) ok)) ok
•
 (l_.test p then loop else ok) ok
•
 test p then loop else ok
•
 loop  loop  loop  loop  …
COS 597B
47
Example Applications
Eliminate redundant annotations:
lx.R{ly.R{e}} = lx.ly.R{e}
Decrease stack inspection costs:
e = test p then (enable p in e) else e
COS 597B
48
Axiomatic Equivalence
Can give a sound set of equations  that
characterize =. Example axioms:
•  is a congruence (preserved by contexts)
• (lx.e) v  e{v/x} (beta equivalence)
• x  fv(v)  lx.v  v
• enable p in o  o
• enable p in (enable q in e) 
enable q in (enable p in e)
• R  S  R{S{e}}  S{e}
• R{S{enable p in e}} 
R{p}{S{enable p in e}}
• … many, many more
 Implies =
COS 597B
49
Example: Tail Calls
Ordinary evaluation:
R{(lx.S{e}) v}  R{S{e{v/x}}}
Tail-call eliminated evaluation:
R{(lx.S{e}) v}  S{e{v/x}}
Not sound in general!
But OK in special cases.
COS 597B
50
Example: Tail Calls
Suppose R  S. Then:
R{(lx.S{e}) v}
 R{S{e{v/x}}}
 S{e{v/x}}
 S{e}{v/x}
(lx.S{e}) v
In particular, code within a protection domain
can safely make tail calls to other code in that
domain.
COS 597B
51
Example: Higher-order Code
main = System [lh.(h ok ok)]
fileHandler =
System[ls.lc.l_.c (readFile s)]
leak = Applet[ls.output s]
main(l_.Applet{fileHandler “f2” leak})
COS 597B
52
Example: Higher-order Code
•
main(l_.Applet{fileHanler “f2” leak})
• * System{Applet{fileHandler “f2” leak} okS}
• * System{Applet{System{System{
l_.System{leak (readFile “f2”)}}}} okS}
• * System{l_.System{leak (readFile “f2”)} okS}
• * System{System{leak <f2 contents>}}
• * System{System{Applet{output <f2 contents>}}}
• * System{System{Applet{ok}}}
• * ok
COS 597B
53
Discussion
 Problem: Applets returning closures that
circumvent stack inspection.
 Possible solution:
 Values of the form: R{v} (i.e. keep track of the
protection domain of the source)
 Similarly, one could have closures capture their
current security context
 Integrity analysis (i.e. where data comes from)
 Fournet & Gordon prove some properties of
strengthened versions of stack inspection.
COS 597B
54
Conclusions
 What security principles does the Java model
obey? To what extent?







Open design?
Economy of mechanism?
Minimal trusted computing base?
Security as process?
Least privilege?
Fail-safe defaults?
Psychological acceptability?
COS 597B
55
Download