Wyvern: Designing a Language for Security Jonathan Aldrich - - PowerPoint PPT Presentation

wyvern designing a language for security
SMART_READER_LITE
LIVE PREVIEW

Wyvern: Designing a Language for Security Jonathan Aldrich - - PowerPoint PPT Presentation

Wyvern: Designing a Language for Security Jonathan Aldrich contributions from: Aaron Craig aldrich@cs.cmu.edu Justin Lubin http://www.cs.cmu.edu/~aldrich/ Darya Melicher Cyrus Omar Alex Potanin Anlun Xu Valerie Zhao 17-396: Language


slide-1
SLIDE 1

Wyvern: Designing a Language for Security

Jonathan Aldrich

aldrich@cs.cmu.edu http://www.cs.cmu.edu/~aldrich/ 17-396: Language Design and Prototyping Spring 2020

School of Computer Science contributions from: Aaron Craig Justin Lubin Darya Melicher Cyrus Omar Alex Potanin Anlun Xu Valerie Zhao

slide-2
SLIDE 2

Software security is a big problem!

2

lodash node module before 4.17.5 suffers from a Modification of Assumed-Immutable Data (MAID) vulnerability via defaultsDeep, … Prototype pollution attack (lodash) The 10 Worst Security Vulnerabilities of 2018 #3: The pdfinfojs NPM module for versions <= 0.3.6 allows for command injection, allowing an attacker to execute arbitrary commands to the machine.

October 17, 2018 Security flaw in libssh leaves thousands of servers at risk of hijacking

slide-3
SLIDE 3

Why Systems are Vulnerable?

  • We “know” how to code securely
  • Follow the rules: CERT, Oracle, …
  • Technical advances: type, memory safety
  • But we still fail too often!
  • Root causes
  • Coding instead of engineering
  • Human limitations
  • Unusable tools

3

slide-4
SLIDE 4

Our Approach: Usable Architecture-Based Security

4

Secure systems development

Outline – 3 issues

  • Tampering w/mutable data

 Immutability

  • Command injection

 Type-specific languages

  • Resource use

 Capabilities and effects

Bridge icon credit: iconsmind.com Lock icon credit: Appzgear at flaticon.com Wyvern credit: Zigeuner

Engineering:

An architecture/design perspective

Settings

  • Java (some studies)
  • Wyvern, a programming

language designed following these principles

Formal modeling: A mathematical perspective Usability:

A human perspective

slide-5
SLIDE 5

Immutability: An Architectural Perspective

  • Architecture: “the set of principal design decisions about

the system” [Garlan and Shaw 1996; Taylor et al. 2009]

  • Typically large in scope
  • Non-architectural
  • final in Java: one field only, non-transitive
  • const in C++: protects through one reference only
  • Both weak reasoning: partial protection of data structure
  • Architectural
  • Transitive immutability: entire data structure protected
  • Strong reasoning – for security, concurrency, etc.
  • Interview studies: programmers want guarantees that only

transitive immutability can provide [Coblenz et al. ICSE 2017]

5

slide-6
SLIDE 6

Formal modeling: enforcing immutability

  • How to enforce transitive immutability, technically?
  • Design decisions based on type systems / soundness proofs

6

Formal grammar Static semantics Dynamic semantics

slide-7
SLIDE 7

Usability Experiments

  • 20 experienced Java programmers, 10 each in Java and Glacier
  • Compared errors/vulnerabilities and completion rates (Java  Glacier)
  • Unsuprising: no errors in Glacier condition
  • Surprising (perhaps): Glacier didn’t slow people down much
  • Usability results still uncommon for type systems
  • We should do more!

7

errors completion Enforcing immutability 10  0 10  7 FileRequest.execute() security task 4  0 8  8 HashBucket.put() task 7  0 10  7

slide-8
SLIDE 8

Wyvern

  • Design goals
  • Sound, modern language design
  • Type- and memory-safe, mostly functional, advanced module system
  • Incorporate usability principles [Coblenz et al. Onward! 2018]
  • Security mechanisms built in
  • E.g. cleaner than Glacier retrofit to Java
  • Immutability support
  • Default: transitive immutability
  • resource indicates types abstracting OS resources or mutable state

8

http://wyvernlang.github.io/

Demo: Immutability in Wyvern (examples/types/person.wyv) Discuss: how is immutability cleaner in Wyvern than in Glacier?

slide-9
SLIDE 9

Our Approach: Usable Architecture-Based Security

9

Immutability in Wyvern Engineering:

Transitive immutability has architectural benefits

Formal modeling: Proof of transitive immutability

Outline – 3 issues

  • Tampering w/mutable data

 Immutability

  • Command injection

 Type-specific languages

  • Resource use

 Capabilities and effects

Settings

  • Java (some studies)
  • Wyvern, a programming

language designed following these principles

Usability:

Simple design, experimentally proven effective

slide-10
SLIDE 10

SQL Command Injection

10

Example

String s = "SELECT * FROM Students WHERE name ='" + studentName + "';" "SELECT * FROM Students WHERE name ='Robert'; DROP TABLE Students; --';"

credit XKCD: HTTP://XKCD.COM/327/

Now plug in the name: Robert'; DROP TABLE Students; -- The data now includes an injected SQL command

Many similar issues

  • HTML (cross-site scripting)
  • Shell scripts (command

injection)

slide-11
SLIDE 11

SQL Injection: a Solved Problem?

PreparedStatement s = connection.prepareStatement( "SELECT * FROM Students WHERE name = ?;"); s.setString(1, userName); s.executeQuery();

  • Evaluation
  • Usability: unnatural, verbose
  • Design: string manipulation captures domain poorly
  • Language semantics: largely lost – just strings
  • No typechecking, IDE services, …

11

X X X

Prepare a statement with a hole Fill the hole securely Discuss: why might this solution be less than satisfactory?

slide-12
SLIDE 12

Wyvern: Usable Secure Programming

  • A SQL query in Wyvern

connection.executeQuery(~) SELECT * FROM Students WHERE name = {studentName}

  • Hypothesis: Wyvern version more natural and more usable
  • No empirical evaluation, yet
  • But Omar et al. [ICSE 2012] shows benefits of similar DSL IDE

plugins

12

~ introduces a domain- specific language (DSL)

  • n the next indented lines

Semantically rich DSL. Can provide typchecking, syntax highlighting, …autocomplete, … Safely incorporates dynamic data—as data, not a command

slide-13
SLIDE 13

Technical Challenge: Syntax Conflicts

  • Language extensions as libraries has been tried before
  • Example: SugarJ/Sugar* [Erdweg et al, 2010; 2013]

import XML, HTML val snippet = ~ How do I <b>parse</b> this example?

13

Is it XML or HTML?

slide-14
SLIDE 14

Syntax Conflicts: Wyvern’s Solution

import metadata XML, HTML val snippet : XML = ~ How do I <b>parse</b> this example?

14

metadata keyword indicates we are importing syntax, not just a library No ambiguity: the compiler loads the unique parser associated with the expected type XML Syntax of language completely unrestricted – indentation separates from host language

slide-15
SLIDE 15

Thinking About Wyvern’s Solution

import metadata XML, HTML, SQL val snippet : XML = ~ How do I <b>parse</b> this example? connection.executeQuery(~) SELECT * FROM Students WHERE name = {studentName}

15

Discuss: what might be possible downsides of this design?

slide-16
SLIDE 16

Technical Challenge: Semantics

import metadata SQL val connection = SQL.connect(…) val studentName = input(…) connection.executeQuery(~) SELECT * FROM Students WHERE name = {studentName}

16

Language definition includes custom typechecker – can verify query against database schema SQL extension has access to variables and their types in Wyvern host language Splicing theory ensures capture- avoiding substitution in code generated by SQL extension – safe to use host language variables Q: Is it safe to run custom parser at compile time? A: Yes – immutability types used to ensure imported metadata is purely functional, has no network access, etc.

slide-17
SLIDE 17

Wyvern demo

  • wyvern/examples/tsls
  • formatstringClient.wyv (format strings)
  • postfixClient.wyv (list and postfix arithmetic)

17

slide-18
SLIDE 18

Our Approach: Usable Architecture-Based Security

18

DSL support in Wyvern Engineering:

Express design in domain-specific way

Formal modeling: Type safety, variable hygiene, conflict-free extensions

Outline – 3 issues

  • Tampering w/mutable data

 Immutability

  • Command injection

 Domain-specific languages

  • Resource use

 Capabilities and effects

Settings

  • Java (some studies)
  • Wyvern, a programming

language designed following these principles

Usability:

Natural syntax, enabling IDE suppoert

slide-19
SLIDE 19

Resource Use

  • SQL extensions are nice!
  • But what if people use a low-level, string-based library anyway?
  • More broadly, what if people misuse resource-access libraries?

19

slide-20
SLIDE 20

What might code do to system resources?

  • Example scenario: constraining plugins

20

Are these plugins safe? Could a malicious plugin delete my files?

slide-21
SLIDE 21

What might code do to system resources?

  • What can a plugin do?
  • File reads, writes?
  • Log an error message?
  • Like a file write, but more abstract

21

My app Plugin

slide-22
SLIDE 22

What might code do to system resources?

  • Goal: enforce architectural layering
  • Application code gets data using a
  • Query ADT, which is implemented via a
  • SQL library, which sends commands via a
  • Network driver, which talks to database
  • Security constraints
  • Network used only for database queries
  • No direct use of string-based SQL library
  • Possible command injection
  • Abstraction of system resources
  • Application does safe queries
  • Query ADT does unsafe queries
  • Network driver does network access

22

String-based SQL library Query ADT Application code Network driver

[Dijkstra 1968]

slide-23
SLIDE 23

Two views of the resource use problem

23

How to reason formally about resource use? How to practically enforce resource use?

Can we be just as lightweight as the practical approach, but retain formal reasoning?

slide-24
SLIDE 24

Formalist: Let’s check this statically!

24

An effect system sounds like a good idea!

slide-25
SLIDE 25

Checking Resource Use with Effects

  • Effect systems [Lucassen & Gifford 88]
  • Annotate each function with its effects
  • Our setting: effects are actions on resources
  • {passwordFile.read, wikipediaURL.request, …}

type File effect read def readContents(): {this.read} String module def myPlugin(f:File) def countWords() : { } Int val contents = f.readContents() contents.split(’ ’).size()

25

File resources define a read effect (cf. type members in Scala) readContents has a read effect on this file myPlugin is a functor that is instantiated with a File What are the effects of countWords()? ?

slide-26
SLIDE 26

Checking Resource Use with Effects

  • Effect systems [Lucassen & Gifford 88]
  • Annotate each function with its effects
  • Our setting: effects are actions on resources
  • {passwordFile.read, wikipediaURL.request, …}

type File effect read def readContents(): {this.read} String module def myPlugin(f:File) def countWords() : {f.read} Int val contents = f.readContents() contents.split(’ ’).size()

26

File resources define a read effect (cf. type members in Scala) readContents has a read effect on this file myPlugin is a functor that is instantiated with a File readContents has effect f.read, so countWords does too

slide-27
SLIDE 27

Checking Architectural Layering

// in signature of the rawSQL module effect UnsafeQuery type Connection def connect(…) : Connection def query(q:String) : {UnsafeQuery} SQLResult // client code def getData(input : String) : Data rawSQL.query("SELECT * FROM Students WHERE name ='“ + input + "';“)

27

Query operations have an UnsafeQuery effect The unsafe SQL library defines an UnsafeSQL effect Has effect rawSQL.UnsafeQuery Error: getData() must declare effect rawSQL.UnsafeQuery

slide-28
SLIDE 28

Checking Architectural Layering

// in signature of the rawSQL module effect UnsafeQuery type Connection def connect(…) : Connection def query(q:String) : {UnsafeQuery} SQLResult // client code def getData(input : String) : {rawSQL.UnsafeQuery} Data rawSQL.query("SELECT * FROM Students WHERE name ='“ + input + "';“)

28

Query operations have an UnsafeQuery effect The unsafe SQL library defines an UnsafeSQL effect Has effect rawSQL.UnsafeQuery All dangerous code marked with effect

slide-29
SLIDE 29

Effect Abstraction

  • Issue: won’t users of the safeSQL library have an

UnsafeQuery effect, if safeSQL is built on rawSQL?

module def safeSQL(rawSQL:RawSQL) : SafeSQL type SQL val command : String … effect SafeQuery = rawSQL.UnsafeQuery def query(SQL) : {SafeQuery} SQLResult …

29

Defines a SQL ADT The safeSQL functor uses a rawSQL module The SafeQuery effect is defined in terms of UnsafeQuery. Now clients have effect safeSQL.SafeQuery

slide-30
SLIDE 30

Opaque Signature Ascription

  • We can hide the definition of an effect
  • Abstract effects – analogous to abstract types in ML modules

[MacQueen, 1986]

30

module def safeSQL(rawSQL:RawSQL) : SafeSQL type SQL val command : String … effect SafeQuery = rawSQL.UnsafeQuery def query(SQL) : {SafeQuery} SQLResult … type SafeSQL type SQL // abstract effect SafeQuery // abstract def query(SQL) : {SafeQuery} SQLResult

slide-31
SLIDE 31

Effect abstraction  Effect polymorphism

  • We can now encode effect polymorphism
  • Cf. type members  type polymorphism in Scala (and Wyvern)

// with polymorphism sugar def twice[effect E](f : Int -> {E} Int, x:Int) : {E} Int f(f(x)) twice[file.write](…) // the desugared version, using only effect members type EffectHolder effect E def twice(e:EffectHolder, f : Int -> {e.E} Int, x:Int) : {e.E} Int f(f(x)) twice(new EffectHolder{effect e=file.write}, …)

31

slide-32
SLIDE 32

Abstraction all the way down

  • Primordial effect: the foreign function interface
  • All other I/O effects defined in terms of this
  • Can also “fake” an effect (no underlying I/O)

module net(java:Java) import java:wyvern.utils.net.javaPacketUtils effect Network = system.FFI type Packet … def send(p:Packet) : {Network} Unit javaPacketUtils.send(p)

32

The net functor takes the Java FFI object as an argument Methods imported from Java automatically have the system.FFI effect Network is an abstract effect defined in terms of system.FFI Calls a Java function, therefore has system.FFI effect; abstracted to clients as a Network effect

slide-33
SLIDE 33

Demo – Effects in Wyvern

33

rawSQL safeSQL Application code JDBC driver

Discuss this effect system design. Compare to:

  • Java’s exception system
  • A system with only one built-in “I/O effect”
  • No effects at all
  • Other points of comparison?
slide-34
SLIDE 34

Is Abstraction Safe?

  • The safeSQL abstracts the UnsafeQuery effect

as a SafeQuery effect

  • OK; safeSQL protects from command injection
  • But couldn’t a malicious library also do this?
  • Idea: analyze code for abstraction
  • UnsafeQuery is abstracted only by safeSQL, and only

as a SafeQuery

  • Currently formalizing and implementing this

34

rawSQL safeSQL Application code JDBC driver

slide-35
SLIDE 35

Two much annotation?

  • Effect system overhead causes problems
  • E.g. Java’s checked exceptions
  • Routinely bypassed using unchecked exceptions
  • Inference [Talpin&Jouvelot 1994] is a solution, but has tradeoffs
  • Avoids need to annotate in many places
  • Only applies if you have the code
  • Usability issues
  • can fail because of something deep in the code
  • can succeed, then fail if the code changes

35

Not sure I want to write effects everywhere!

slide-36
SLIDE 36

Object capabilities

  • Capability: an unforgeable token controlling access to a

resource [Dennis & Van Horn 1966]

  • Benefits
  • Simple approach to security
  • Principle of least privilege [Saltzer 1974]
  • Object capability: object reference grants access to resource
  • Recent research: E [Miller 2006], Joe-E [Mettler et al. 2010]
  • Frozen Realms proposal for JavaScript
  • Note: our capabilities are object references (dynamic)
  • Capability has also been used for permissions in a type system

(static)

36

slide-37
SLIDE 37

Capability Safety

  • No ambient authority
  • Code cannot use system resources by default
  • main gets a capability to system resources from OS
  • Other modules can use resources only if main passes it to them
  • Pass only the capabilities each module needs
  • Often at functor instantiation time
  • Formalized as capability safety [Maffeis et al. 2010]
  • Adapted for Wyvern [Melicher et al. 2017]

37

main module Another module Another module Another module Operating System

Passes capabilities to Passes capabilities to

slide-38
SLIDE 38

Capability Safety

// the safeSQL module module def safeSQL(stringSQL : db.StringSQL) type SSQL = … type Sselect = … def select(row:String):SQLSelect = … // the main program require db.stringSQL import db.safeSQL import modules.sqlApplication val sql = safeSQL(stringSQL) val app = sqlApplication(sql) app.run()

38

stringSQL safeSQL sqlApplication

safeSQL can’t just import StringSQL; it must be passed a capability main requires a stringSQL capability from the OS These modules are pure (stateless) functors and can be imported We instantiate the modules, passing capabilities

slide-39
SLIDE 39

Capabilities all the way down

  • The primordial capability is the FFI
  • “require db.stringSQL” instantiates

stringSQL with a java FFI capability:

// the stringSQL module module def stringSQL(java : Java) import java:wyvern.JDBC.utils type SQL def query():String … // the main program, now desugared require java import db.stringSQL val ssql = stringSQL(java) …

39

stringSQL safeSQL sqlApplication java (JDBC driver)

main requires a java FFI capability stringSQL is a functor that needs a java FFI capability to use JDBC Import and instantiate stringSQL, then the

  • ther modules
slide-40
SLIDE 40

Authority attenuation

  • Capabilities give programs authority to

access resources

  • A capability can attenuate another by

wrapping it in a restricted interface

  • Example: safeSQL wraps stringSQL, SQL-

encoding pasted strings to avoid command injection

40

stringSQL safeSQL sqlApplication java

The java FFI capability can access any system resource stringSQL attenuates that to

  • nly accessing SQL databases

safeSQL attenuates that to only permit safe query composition

Provided the wrappers are correct: * sqlApplication can only access a database * SQL injection vulnerabilities impossible

slide-41
SLIDE 41

Demo – Capabilities in Wyvern

41

stringSQL safeSQL sqlApplication java

Discussion

  • Is the capability model intuitive?
  • How does it compare to other security

models you may be aware of?

  • Would you rather use effects or capabilities?
slide-42
SLIDE 42

Comparing these mechanisms

Effects

  • Static, mechanical reasoning
  • Effect annotation on a function
  • Requires annotations
  • Can be burdensome
  • Support abstraction
  • SafeQuery abstracts UnsafeQuery
  • Build up from FFI effect

Capabilities

  • Reason using dynamic semantics
  • Who has which capability?
  • No annotations required
  • But must pass capabilities explicitly
  • Support attenuation
  • safeSQL attenuates stringSQL
  • Build up from java capability

42

Idea: can we combine these mechanisms?

  • Nearly as lightweight as capabilities
  • Retain formal reasoning of effects
  • Explain, formally, why capabilities are useful!

Capabilities are neat…but what do they really buy us? Formally, no one really knows.

slide-43
SLIDE 43

Bounding effects with capabilities

  • We can bound a module’s effects by its capabilities
  • No need to effect-annotate the module
  • Note: requires capability safety!

module def client(safeSQL : SafeSQL) : Client import … // other code

43

Client can have effect safeSQL.SafeQuery (and nothing else) Imports must be pure

  • no effects

Safe SQL DSL library Client code

Scales up – most application code may be unannotated

slide-44
SLIDE 44

Effect bounding demo

44

Logger Editor Plugin uses

Annotated Not Annotated Configured to log to a file or the network

Legend

slide-45
SLIDE 45

Capability effect computation: examples

What are the effects enabled by a capability of a given type?

  • 1. effcap(Unit A Unit) = {A}
  • 2. effcap(Unit A Unit B Unit) = {A,B}
  • Client can have effect A and then effect B
  • 3. effcap((Unit A Unit) B Unit) = {B}
  • Client can have effect B, but does not gain the ability to have

effect A because the client produces the argument

  • 4. effcap(((Unit A Unit) B Unit) C Unit) = {A,C}
  • Client can have effect C by calling the function, and effect A by

providing a function that gets a (Unit A Unit) and invokes it

45

slide-46
SLIDE 46

Lifting effect polymorphism

module def repeaterPlugin(defaultLogger : Logger) var logger : Logger = defaultLogger def log(msg:String) : Unit = … def setLogger(aLogger : Logger) : Unit logger = aLogger

46

We would like to assign this function an effect- polymorphic type But some functions might assign to local state, so the effect of log and setLogger must be bounded by the overall effect of the module (cf. polymorphism and state, more generally) Our solution is lifts poly- morphism to the module level, where the state is created

slide-47
SLIDE 47

Comparison and tradeoffs vs. inference

Effect Inference

  • Only requires effects
  • Requires code
  • Failure may depend on code
  • E.g. large components, evolution

Effect Bounds

  • Requires capabilities & effects
  • Requires only type
  • Failure depends only on type
  • E.g. large components, evolution
  • Explains value of capabilities

for formal reasoning

47

slide-48
SLIDE 48

Capabilities and Effects: So Happy Together

  • Goal: controlling system resources
  • Two approaches
  • Effect system, supporting abstraction
  • Capability safety, supporting attenuation
  • A link between them: bounding effects with capabilities
  • Use lightweight approach for many components
  • Formally reason about the effect of all components
  • Bonus: formal explanation of the reasoning power of capabilities

48

slide-49
SLIDE 49

Our Approach: Usable Architecture-Based Security

49

Effects and capabilities in Wyvern Engineering:

Architectural restrictions

  • n resource use

Formal modeling: Effect- and capability-safety, effect bounds

Outline – 3 issues

  • Tampering w/mutable data

 Immutability

  • Command injection

 Domain-specific languages

  • Resource use

 Capabilities and effects

Settings

  • Java (some studies)
  • Wyvern, a programming

language designed following these principles

Usability:

Bound effects based on architecture

slide-50
SLIDE 50

Our Approach: Usable Architecture-Based Security

50

Secure systems development Engineering:

An architecture/design perspective

Formal modeling: A mathematical perspective

Outline – 3 issues

  • Tampering w/mutable data

 Immutability

  • Command injection

 Domain-specific languages

  • Resource use

 Capabilities and effects

Settings

  • Java (some studies)
  • Wyvern, a programming

language designed following these principles

Usability:

A human perspective