Synode: Understanding and Automatically Preventing Injection Attacks - - PowerPoint PPT Presentation

synode understanding and automatically preventing
SMART_READER_LITE
LIVE PREVIEW

Synode: Understanding and Automatically Preventing Injection Attacks - - PowerPoint PPT Presentation

Synode: Understanding and Automatically Preventing Injection Attacks on Node.js Cristian-Alexandru Staicu 1 Michael Pradel 1 Ben Livshits 2 1 TU Darmstadt 2 Imperial College London, Brave Software February 20, 2018 This Talk Node.JS and


slide-1
SLIDE 1

Synode: Understanding and Automatically Preventing Injection Attacks on Node.js

Cristian-Alexandru Staicu1 Michael Pradel1 Ben Livshits2

1TU Darmstadt 2Imperial College London, Brave Software

February 20, 2018

slide-2
SLIDE 2

This Talk

Node.JS and Injections Empirical Study Synode Evaluation

slide-3
SLIDE 3

This Talk

Node.JS and Injections Empirical Study Synode Evaluation

slide-4
SLIDE 4

1

Node.js 101

JS application JS engine

slide-5
SLIDE 5

1

Node.js 101

JS application JS engine Node.JS bindings OS fs, exec

slide-6
SLIDE 6

1

Node.js 101

JS application JS engine Node.JS bindings OS fs, exec Node Package Manager

slide-7
SLIDE 7

1

Node.js 101

JS application JS engine Node.JS bindings OS fs, exec Node Package Manager Node Security Project

slide-8
SLIDE 8

2

Typical Node.JS Application

Node.JS application strings utility templates engine DB access headers parser vulnerable module ... ... ...

slide-9
SLIDE 9

3

Running Example

function backupFile(name, ext) { var cmd = []; cmd.push("cp"); cmd.push(name + "." + ext); cmd.push("˜/.localBackup/"); exec(cmd.join(" ")); }

slide-10
SLIDE 10

3

Running Example

function backupFile(name, ext) { var cmd = []; cmd.push("cp"); cmd.push(name + "." + ext); cmd.push("˜/.localBackup/"); exec(cmd.join(" ")); }

Malicious Payload

backupFile("-h && rm -rf * && echo ", "")

slide-11
SLIDE 11

4

This Talk

Node.JS and Injections Empirical Study Synode Evaluation

slide-12
SLIDE 12

5

npm Codebase

236,337

packages

816,840,082

lines of JavaScript code

7,685

number of packages containing exec

2.471

average number of package dependences

>40,000

C files

9,110

number of packages containing eval

February 2016

slide-13
SLIDE 13

6

Dependences on Injection APIs

5 10 15 20 e x e c e v a l e x e c

  • l

e v e l

  • 1

e v a l

  • l

e v e l

  • 1

e x e c

  • l

e v e l

  • 2

e v a l

  • l

e v e l

  • 2

t

  • t

a l

  • l

e v e l

  • 2

Percentage of npm modules

slide-14
SLIDE 14

7

Data Passed to Injection APIs

Manual inspection of 150 call sites

eval exec

0% 10% 20% 30% code loading JSON higher-order fct. property read 0% 20% 40% 60% simple OS command piped commands local script

slide-15
SLIDE 15

7

Data Passed to Injection APIs

Manual inspection of 150 call sites

eval exec

0% 10% 20% 30% code loading JSON higher-order fct. property read 0% 20% 40% 60% simple OS command piped commands local script

58% contain user-controlled data, out of which: 90% perform no check on this data 9% use regular expressions

slide-16
SLIDE 16

8

Submitted Bug Reports

Affected module Confirmed Time until fixed

mixin-pro

yes 1 day

modulify

no –

proto

yes 155 days*

mongoosify

yes 73 days

summit

yes –

microservicebus.node

yes –

mobile-icon-resizer

yes 2 days

m-log

– –

mongo-edit

– –

mongo-parse

yes –

mock2easy

– –

mongui

– –

m2m-supervisor

– –

nd-validator

– –

nameless-cli

– –

node-mypeople

– –

mongoosemask

– –

kmc

– –

mod

– –

growl

yes – – indicates a lack response and * an incomplete fix

180 days after reporting

slide-17
SLIDE 17

9

Lessons Learned

multiple dependences

  • n average each module has 2.5 direct dependences

no sanitization

  • nly 9% use sanitization, often broken

unresponsive developers

within six months only 25% of the issues were fixed

slide-18
SLIDE 18

10

This Talk

Node.JS and Injections Empirical Study Synode Evaluation

slide-19
SLIDE 19

11

Safe Use of Modules with Synode

Node.JS application strings utility templates engine DB access headers parser vulnerable module ... ... ...

slide-20
SLIDE 20

12

Overview of Synode

npm module Static analysis

slide-21
SLIDE 21

12

Overview of Synode

npm module Static analysis Safe behavior Statically safe programs

slide-22
SLIDE 22

12

Overview of Synode

npm module Static analysis Safe behavior Statically safe programs Program rewriting Templates List of safe nodes

slide-23
SLIDE 23

12

Overview of Synode

npm module Static analysis Safe behavior Statically safe programs Program rewriting Templates List of safe nodes Dynamic policy enforcement Runtime inputs

slide-24
SLIDE 24

13

Static Phase

  • 1. Intra-procedural backward data flow analysis:

Over-approximates strings passed to injection APIs Unknown parts to be filled at runtime

slide-25
SLIDE 25

13

Static Phase

  • 1. Intra-procedural backward data flow analysis:

Over-approximates strings passed to injection APIs Unknown parts to be filled at runtime

function backupFile (name , ext ) { var cmd = [ ] ; cmd . push ("cp") ; cmd . push (name + "." + ext ) ; cmd . push ("˜/.localBackup/") ; exec (cmd . j o i n (" ") ) ; }

”cp $name.$ext ˜/.localBackup/” ”$hole”

slide-26
SLIDE 26

13

Static Phase

  • 1. Intra-procedural backward data flow analysis:

Over-approximates strings passed to injection APIs Unknown parts to be filled at runtime

function backupFile (name , ext ) { var cmd = [ ] ; cmd . push ("cp") ; cmd . push (name + "." + ext ) ; cmd . push ("˜/.localBackup/") ; exec (cmd . j o i n (" ") ) ; }

”cp $name.$ext ˜/.localBackup/” ”$hole” ”˜/.localBackup/”

slide-27
SLIDE 27

13

Static Phase

  • 1. Intra-procedural backward data flow analysis:

Over-approximates strings passed to injection APIs Unknown parts to be filled at runtime

function backupFile (name , ext ) { var cmd = [ ] ; cmd . push ("cp") ; cmd . push (name + "." + ext ) ; cmd . push ("˜/.localBackup/") ; exec (cmd . j o i n (" ") ) ; }

”cp $name.$ext ˜/.localBackup/” ”$hole” ”˜/.localBackup/” ”$name.$ext ˜/.localBackup/”

slide-28
SLIDE 28

13

Static Phase

  • 1. Intra-procedural backward data flow analysis:

Over-approximates strings passed to injection APIs Unknown parts to be filled at runtime

function backupFile (name , ext ) { var cmd = [ ] ; cmd . push ("cp") ; cmd . push (name + "." + ext ) ; cmd . push ("˜/.localBackup/") ; exec (cmd . j o i n (" ") ) ; }

”cp $name.$ext ˜/.localBackup/” ”$hole” ”˜/.localBackup/” ”$name.$ext ˜/.localBackup/” ”cp $name.$ext ˜/.localBackup/”

slide-29
SLIDE 29

14

Static Phase

  • 2. Synthesize runtime policy using templates:

Enforce structure via partial AST For unknown parts allow only safe nodes

slide-30
SLIDE 30

14

Static Phase

  • 2. Synthesize runtime policy using templates:

Enforce structure via partial AST For unknown parts allow only safe nodes ”cp $name.$ext ˜/.localBackup” command literal cp list literal literal ?? ˜/.localBackup command args value value value

slide-31
SLIDE 31

15

Runtime Phase

Enforce policy on strings passed to injection APIs Policy: command literal cp list literal literal ?? ˜/.localBackup command args value value value

slide-32
SLIDE 32

15

Runtime Phase

Enforce policy on strings passed to injection APIs Policy: command literal cp list literal literal ?? ˜/.localBackup command args value value value Runtime string: ”cp file.txt ˜/.localBackup” command literal cp list literal literal file.txt ˜/.localBackup command args value value value

slide-33
SLIDE 33

15

Runtime Phase

Enforce policy on strings passed to injection APIs Policy: command literal cp list literal literal ?? ˜/.localBackup command args value value value Runtime string: ”cp file.txt ˜/.localBackup” command literal cp list literal literal file.txt ˜/.localBackup command args value value value

slide-34
SLIDE 34

16

Runtime Phase

Runtime string: ”cp x || rm * -rf ˜/.localBackup” command literal cp list literal literal x ˜/.localBackup || command literal rm list glob literal *

  • rf

command args value value value control next command args value value value

slide-35
SLIDE 35

16

Runtime Phase

Runtime string: ”cp x || rm * -rf ˜/.localBackup” command literal cp list literal literal x ˜/.localBackup || command literal rm list glob literal *

  • rf

command args value value value control next command args value value value

slide-36
SLIDE 36

17

This Talk

Node.JS and Injections Empirical Study Synode Evaluation

slide-37
SLIDE 37

18

Evaluation: Static Phase

Setup 51K call sites of injection APIs Precision 36.7% of the call sites statically safe 63.3% to be checked at runtime Context most call sites have at least:

10 constant characters per template 1 unknown per template

Performance 4.4 seconds per module

slide-38
SLIDE 38

19

Evaluation: Runtime Phase

Setup 24 modules 56 benign and 65 malicious inputs Results zero malicious inputs that we do not stop five benign inputs that we incorrectly stop

  • verhead: 0.74 milliseconds per call
slide-39
SLIDE 39

20

Conclusions

Study of injection vulnerabilities First large-scale study of Node.js security exec and eval are prevalent in npm ecosystem Developers are slow to react

slide-40
SLIDE 40

20

Conclusions

Study of injection vulnerabilities First large-scale study of Node.js security exec and eval are prevalent in npm ecosystem Developers are slow to react

slide-41
SLIDE 41

20

Conclusions

Study of injection vulnerabilities First large-scale study of Node.js security exec and eval are prevalent in npm ecosystem Developers are slow to react Prevention of injections Automatic and easy to deploy https://github.com/sola-da/Synode Small overhead and high accuracy

slide-42
SLIDE 42

20

Conclusions

Study of injection vulnerabilities First large-scale study of Node.js security exec and eval are prevalent in npm ecosystem Developers are slow to react Prevention of injections Automatic and easy to deploy https://github.com/sola-da/Synode Small overhead and high accuracy Open challenges More precise static analysis Automatic generation of attacks

slide-43
SLIDE 43

20

slide-44
SLIDE 44

21

Example Limitation: Array.map()

var keys = Object.keys(dmenuOpts); var dArgs = keys.map(function(flag) { return ’-’ + flag + ’ "’ + dmenuOpts[flag] + ’"’; }).join(’ ’); var cmd = ’echo | dmenu -p "Password:" ’ + dArgs; exec(cmd);

Inferred template

’echo | dmenu -p "Password:" $dArgs’

slide-45
SLIDE 45

22

Implementation

Intraprocedural static analysis Based on Google Closure Compiler Policy for unknown parts:

exec: literal eval: literal, identifier, property, array expression, object

expression, member expression, expression statement

slide-46
SLIDE 46

23

Beyond eval and exec

vm.runIn*Context()

var vm = require(’vm’); vm.runInThisContext( "console.log(’" + input + ");");

execa module (1,000 dependents)

module.exports.shell = function(cmd) { args = [’-c’, cmd] childProcess.spawnSync("/bin/sh", args); }

slide-47
SLIDE 47

24

Why is the Application Domain Unique?

20 out of 66 advisories are injections (Node Security Project) Bad habits Unnecessary code reuse (see left-pad) No sandbox