static enforcement of security with types christian skalka and scott smith johns hopkins university
Post on 20-Dec-2015
213 views
TRANSCRIPT
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