Static Enforcement of Security with Types Christian Skalka and Scott Smith Johns Hopkins University.
-
date post
20-Dec-2015 -
Category
Documents
-
view
212 -
download
0
Transcript of Static Enforcement of Security with Types Christian Skalka and Scott Smith Johns Hopkins University.
Static Enforcement of Security with Types
Christian Skalka and Scott Smith
Johns Hopkins University
Background: PL Security
• Non-local execution of code (e.g. Applets) presents new security problems
• Some PLs provide user-level abstractions for security (Ambit, Spi-calculus, Java)
• Built-in mechanisms allow expression and enforcement of various models/policies
Varieties of Security
• Dataflow ensures security of data
• Certified Code (PCC) is an extremely general framework for extensible code security
• Access Control is a flexible system of code ownership and resource authorization
Varieties of Security
• Dataflow ensures security of data
• Certified Code (PCC) is an extremely general framework for extensible code security
• Access Control is a flexible system of code ownership and resource authorization
Overview
• Background: PL Security
• Java JDK 1.2 and stack inspection
• Using types instead of stack inspection
• Security Types: formal properties
• Possible improvements
• Work in Progress
• Conclusion
Java Security
• Java JDK 1.2 provides a system for access control and code security– possibly non-local program execution requires
protection of resources
• All code has a specified owner, granted certain privileges locally
• Resources are protected by a dynamic check (stack inspection)
Stack Inspection
• Stack frames are annotated with names of owners 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
Example: privileged printing
privPrint(f) = (* owned by system *){checkPrivilege(PrintPriv);print(f);
}
foreignProg() = (* owned by Joe *)
{
…; privPrint(file); …;
}
Stack Inspection
(* local policy *)AccessCreds = { Joe = {???},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
(* local policy *)AccessCreds = { Joe = {PrintPriv},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
systemsystem
Main
(* local policy *)AccessCreds = { Joe = {PrintPriv},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
system
PrintPriv
system
PrintPriv
Main
(* local policy *)AccessCreds = { Joe = {PrintPriv},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
system
PrintPriv
system
PrintPriv
joejoe
Main
foreignProg
(* local policy *)AccessCreds = { Joe = {PrintPriv},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
system
PrintPriv
system
PrintPriv
joejoe
systemsystem
Main
foreignProg
privPrint
(* local policy *)AccessCreds = { Joe = {PrintPriv},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
system
PrintPriv
system
PrintPriv
joejoe
systemsystem
Main
foreignProg
privPrint
(* local policy *)AccessCreds = { Joe = {PrintPriv},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
system
PrintPriv
system
PrintPriv
joejoe
systemsystem
Main
foreignProg
privPrint
success(* local policy *)AccessCreds = { Joe = {PrintPriv},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
(* local policy *)AccessCreds = { Joe = {},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
system
PrintPriv
system
PrintPriv
joejoe
systemsystem
Main
foreignProg
privPrint
(* local policy *)AccessCreds = { Joe = {},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Stack Inspection
system
PrintPriv
system
PrintPriv
joejoe
systemsystem
Main
foreignProg
privPrint
failure
(* local policy *)AccessCreds = { Joe = {},…}
(* owned by system *)enablePriv(PrintPriv);foreignProg();
Why Stack Inspection?
• How is it different from a capability system?
• Why not just use an access control matrix and a global set of allowable privileges?– Privileges not held by current code owner are
removed from allowable set
Stack Inspection: Callbacks
• Stack inspection allows security contexts
to be temporarily raised.
Stack Inspection: Callbacks
(* owned by system *)
getIPaddr(url) =
{
checkPriv(IPPriv);
addr = IPlookup(url);
return addr;
}
• Stack inspection allows security contexts
to be temporarily raised:
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
joejoe
getMyIP
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
joejoe
systemsystem
getMyIP
appletIP
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
joejoe
system
IPPriv
system
IPPriv
getMyIP
appletIP
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
joejoe
system
IPPriv
system
IPPriv
joejoe
getMyIP
appletIP
this.source
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
joejoe
system
IPPriv
system
IPPriv
getMyIP
appletIP
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
joejoe
system
IPPriv
system
IPPriv
systemsystem
getMyIP
appletIP
getIPaddr
Callbacks
(* owned by system *)
appletIP(applet) =
{
enablePriv(IPPriv);
url = applet.source();return getIPaddr(url);
}
(* owned by Joe, not
authorized for IPPriv *)
getMyIP() = appletIP(this);
joejoe
system
IPPriv
system
IPPriv
systemsystem
getMyIP
appletIP
getIPaddr
success
A Static Approach
Our thesis: types can statically enforce the Java security model.
• Unsafe programs rejected at compile time
• Need for runtime checks eliminated
• Types are a declaritive form of security policy expression and enforcement
Security Type Examples
(* privPrint needs PrintPriv *)
privPrint : file -{PrintPriv}-> unit
(* PrintPriv in AccessCreds(Joe) *)
foreignProg : unit -{PrintPriv}-> t
(* PrintPriv not in AccessCreds(Joe) *)
foreignProg : *ERROR*, cannot be typed
Security Type Examples
(* enables SomePriv for parameter f *)
privWrap(f) =
{enablePriv(SomePriv);
f();
}
privWrap : (unit -{SomePriv}-> unit) -{}-> unit
Subtyping Security Types
• With monotypes, subtypes allow typing of more safe programs:– privWrap can safely use the identity function id, so privWrap(id)
should be typable
id : unit -{}-> unit
privWrap : (unit -{SomePriv}-> unit) -{}-> unit
Subtyping Security Types
• Security requirements may safely be overestimated
C(fnlt)
u
’’’
C ’’’
unit -{}-> unit <: unit -{SomePriv}-> unitprivWrap(id) : unit
Security Type Judgements
p checkPriv for e : p e :
(checkpriv)
u
Security Type Judgements
p ee’ : p e : ’ p e’ : ’’
u
’ (appl)
p checkPriv for e : p e :
(checkpriv)
u
Security Type Judgements
p ee’ : p e : ’ p e’ : ’’
u
’ (appl)
p checkPriv for e : p e :
(checkpriv)
u
p enablePriv for e : up e :
(enablepriv)
u
A(p)
Security Type Judgements
Formal Properties of the System
S, A e v
S (p, ) :: S’
S, A e secfail
• Stack Inspection is modeled in a language
with well-defined operational semantics:
(secstacks)
• Unsafe expressions reduce to secfail:
Formal Properties of the System
• We prove subject reduction and type safety results for the system– Well-typed programs are not unsafe.
• We prove soundness and completeness results for a type inference algorithm– type system can be transparently layered over
existing system
Type Inference
• Algorithm is standard constraint inference, plus a new constraint satisfiability check:– Privilege sets may contain variables– Privilege set variable constraints may be
recursive
• Satisfiability check is novel, efficient; correctness is proved
Incompleteness of the System
• Java privileges are first-class
• Java programs can conditionally branch on presence/absence of privileges
• Paramaterized privileges, e.g.: fileRead(filename)
• Dynamic access control lists
Work in Progress
• Extend type system to accurately type privilege tests
• Polymorphism
• More sophisticated language features (Java features, modules)
• Readability of types
Conclusion
• Java security model is sound, but dynamic checks impose penalties
• Types can be used to enforce the model, and eliminate these penalties
• Security Types may be inferred efficiently
http://www.cs.jhu.edu/~ces/work.html
Conclusion
• Java security model is sound, but dynamic checks impose penalties
• Types can be used to enforce the model, and eliminate these penalties
• Security Types may be inferred efficiently
http://www.cs.jhu.edu/~ces/work.html
Conclusion
• Java security model is sound, but dynamic checks impose penalties
• Types can be used to enforce the model, and eliminate these penalties
• Security Types may be inferred efficiently
http://www.cs.jhu.edu/~ces/work.html
Conclusion
• Java security model is sound, but dynamic checks impose penalties
• Types can be used to enforce the model, and eliminate these penalties
• Security Types may be inferred efficiently
http://www.cs.jhu.edu/~ces/work.html
Conclusion
• Java security model is sound, but dynamic checks impose penalties
• Types can be used to enforce the model, and eliminate these penalties
• Security Types may be inferred efficiently
http://www.cs.jhu.edu/~ces/work.html