Current Techniques in Language-based Security
David WalkerCOS 441
With slides stolen from:Steve ZdancewicUniversity of Pennsylvania
COS 441 2
Mobile Code Modern languages like Java and C#
have been designed for Internet applications and extensible systems
PDAs, Cell Phones, Smart Cards, …
operating system
web browser
applet applet applet
COS 441 3
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 441 4
Java and C# Security Static Type Systems
Memory safety and jump safety Run-time checks for
Array index bounds Downcasts Access controls
Virtual Machine / JIT compilation Bytecode verification Enforces encapsulation boundaries (e.g. private field)
Garbage Collected Eliminates memory management errors
Library support Cryptography, authentication, …
These lectures
COS 441 5
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 441 6
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
how exactly does it work?
Reasoning about programs that use stack inspection
COS 441 7
Java Security Model
a.classb.classc.classd.classe.class
Domain A
Domain B
Permissions
Permissions
Security PolicyVM Runtime
http://java.sun.com/j2se/1.4.2/docs/guide/security/spec/security-specTOC.fm.html
ClassloaderSecurityManager
COS 441 8
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.RuntimePermissionjava.net.NetPermission java.net.SocketPermission …
COS 441 9
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 441 10
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 441 11
Classloader Hierarchy
ClassLoader
SecureClassLoader URLClassLoader
AppletClassLoader
Primordial ClassLoade
r
COS 441 12
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 441 13
Example Trusted Code
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();}
Code in the System protection domain
COS 441 14
Example Client
class UntrustedApplet { void run() { ... s.FileWrite(“/tmp/foo.txt”, “Hello!”); ... s.FileWrite(“/home/dpw/grades.txt”, “Ginsburg: A+”); ... }}
Applet code obtained from http://www.l33t-hax0rz.com/
COS 441 15
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 441 16
Stack Inspection Example
main(…){ fp = new FilePermission(“/tmp/*”,“write,…”); sm.enablePrivilege(fp); UntrustedApplet.run();}
Policy
Data
base
COS 441 17
Stack Inspection Example
main(…){ fp = new FilePermission(“/tmp/*”,“write,…”); sm.enablePrivilege(fp); UntrustedApplet.run();}
fp
Policy
Data
base
COS 441 18
Stack Inspection Example
main(…){ fp = new FilePermission(“/tmp/*”,“write,…”); sm.enablePrivilege(fp); UntrustedApplet.run();}
void run() { … s.FileWrite(“/tmp/foo.txt”, “Hello!”); …}
fp
Policy
Data
base
COS 441 19
Stack Inspection Example
main(…){ fp = new FilePermission(“/tmp/*”,“write,…”); sm.enablePrivilege(fp); UntrustedApplet.run();}
void run() { … s.FileWrite(“/tmp/foo.txt”, “Hello!”); …}
void fileWrite(“/tmp/foo.txt”, “Hello!”) { fp = new FilePermission(“/tmp/foo.txt”,“write”) sm.checkPermission(fp); /* … write s to file filename … */
fp
Policy
Data
base
COS 441 20
Stack Inspection Example
main(…){ fp = new FilePermission(“/tmp/*”,“write,…”); sm.enablePrivilege(fp); UntrustedApplet.run();}
void run() { … s.FileWrite(“/tmp/foo.txt”, “Hello!”); …}
void fileWrite(“/tmp/foo.txt”, “Hello!”) { fp = new FilePermission(“/tmp/foo.txt”,“write”) sm.checkPermission(fp); /* … write s to file filename … */
fp
Policy
Data
base
Succeed!
COS 441 21
Stack Inspection Example
main(…){ fp = new FilePermission(“/tmp/*”,“write,…”); sm.enablePrivilege(fp); UntrustedApplet.run();}
void run() { … s.FileWrite(“/home/dpw/grades.txt”, “Ginsburg: A+”);}
fp
Policy
Data
base
COS 441 22
Stack Inspection Example
main(…){ fp = new FilePermission(“/tmp/*”,“write,…”); sm.enablePrivilege(fp); UntrustedApplet.run();}
void fileWrite(“…/important.txt”, “kwijibo”) { fp = new FilePermission(“important.txt”, “write”); sm.checkPermission(fp);
fp
Policy
Data
base
void run() { … s.FileWrite(“/home/dpw/grades.txt”, “Ginsburg: A+”);}
Fail
COS 441 23
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
A trusted piece of code could disable a previously granted permission Terminate the stack inspection early
COS 441 24
Stack Inspection AlgorithmcheckPermission(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 441 25
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 441 26
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 441 27
Stack Inspection Literature
Stack Inspection: Theory and VariantsCédric Fournet and Andrew D. Gordon Use operational semantics like in class
Understanding Java Stack InspectionDan S. Wallach and Edward W. Felten Formalize Java Stack Inspection using a special logic
of authentication
COS 441 29
Abstract Stack Inspection Abstract permissions
p,q Permissions (left abstract in the
theory) R,S Principals (sets of permissions)
Hide the details of classloading, etc. Examples:
System = {fileWrite(“f1”), fileWrite(“f2”),…}Applet = {fileWrite(“f1”)}
COS 441 30
sec Syntax Language syntax:
e ::= expressions x variable x.e function e1 e2 application R{e} framed expr enable p in e enable test p then e1 else e2 check perm. fail failure
v ::= x | x.e valueso ::= v | fail outcome
COS 441 31
Framing a Term Models the Classloader that marks the
(unframed) code with its protection domain:
Load(R,x) = x
Load(R,x.e) = x. R{ Load(R,e) }
Load(R,e1 e2) = Load(R,e1) Load(R,e2)
Load(R,enable p in e) = enable p in Load(R,e)
Load(R,test p then e2 else e2)
= test p then Load(R,e1) else Load(R,e2)
Load(R,fail) = fail
COS 441 32
Example
readFile = fileName.System{ test fileWrite(fileName) then
… // primitive file IO (native code) else fail }
Applet{readFile “f2”} -->* fail System{readFile “f2”} -->* <f2 contents>
COS 441 33
sec Operational Semantics Evaluation contexts:
E ::= [] Hole E e Eval function
v E Eval argenable p in E Tag on stack
frame R{E} Stack frame
E models the control stack
COS 441 34
sec Operational SemanticsE[(lx.e) v] --> E[e{v/x}]
E[enable p in v] --> E[v]
E[R{v}] --> E[v]
E[fail] --> fail
E[test p then e else f] --> E[e] if Stack(E) |-- p
E[test p then e else f] --> E[f] if (Stack(E) |-- p)
COS 441 36
Example Evaluation Context
E = Applet{[]}r = (fileName.System{ test fileWrite(fileName) then
… // primitive file IO (native code) else fail } ) “f2”
Applet{readFile “f2”}
COS 441 37
Example Evaluation Context
Applet{readFile “f2”}
E = Applet{[]}r = System{ test fileWrite(“f2”) then
… // primitive file IO (native code) else fail }
COS 441 38
Example Evaluation Context
Applet{System{ test fileWrite(“f2”) then
… // primitive file IO (native code) else fail }}
COS 441 39
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 441 40
Formal Stack Inspection
E’ = Applet{System{[]}}r’ = test fileWrite(“f2”) then
… // primitive file IO (native code) else fail
When does stack E’ allow permissionfileWrite(“f2”)?
Stack(E’) |-- fileWrite(“f2”)
COS 441 41
Formal Stack Inspection
Structure of Stacks:
s ::= . (Empty Stack) | s.R (Stack for code of principal R) | s.enable(p) (Privelege p enabled)
COS 441 42
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 441 43
Abstract Stack Inspection
. |-- p empty stack axiom
s |-- p p Rs.R |-- p
s |-- ps.enable(q) |-- p
protection domain check
p q irrelevant enable
s |= ps.enable(p) |-- p
check enable
COS 441 44
Abstract Stack Inspection
. |= p empty stack enables all
p Rx.R |= p enable succeeds
x |= px.enable(q) |=
p
irrelevant enable
COS 441 45
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 441 46
Example Inequality
ok = x.x
loop = (x.x x)(x.x x) (note: loop )
f = x. let z = x ok in _.zg = x. let z = x ok in _.(x ok)
Claim: f ≠ g
Proof:Let C[] = {[ ] _.test p then loop else ok} ok
COS 441 47
Example Continued
C[f] = {f _.test p then loop else ok} ok • {let z = (_.test p then loop else ok) ok in _.z} ok• {let z = test p then loop else ok in _.z} ok• {let z = ok in _.z} ok• {_.ok} ok• (_.ok) ok• ok stack({ [ ] }) = ..
.. |-- p is not valid
COS 441 48
Example Continued
C[g] = {g _.test p then loop else ok} ok• {let z = (_.test p then loop else ok) ok in _.((_.test p then loop else ok) ok)} ok• {let z = test p then loop else ok in _. ((_.test p then loop else ok) ok)} ok• {let z = ok in _. ((_.test p then loop else ok) ok)} ok• {_. ((_.test p then loop else ok) ok)} ok• (_. ((_.test p then loop else ok) ok)) ok• (_.test p then loop else ok) ok• test p then loop else ok• loop loop loop …
stack([ ] ) = .. |-- p is valid!
return from function ==> pop frame
COS 441 49
Example Applications
Eliminate redundant annotations:
x.R{y.R{e}} = x.y.R{e}
Decrease stack inspection costs:
e = test p then (enable p in e) else e
Formal reasoning about the semantics of stack inspection makes it possible to perform
safe optimizations:
COS 441 50
Axiomatic Equivalence
Can give a sound set of equations that characterize =. Example axioms:
• (x.e) v e{v/x} (beta equivalence)• x fv(v) x.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 441 53
Other Problems Applets returning closures can
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.