Understanding and Automatically Preventing Injection Attacks on Node.js Michael Pradel TU Darmstadt Joint work with Cristian Staicu (TU Darmstadt) and Ben Livshits (Microsoft Research, Redmond) 1
Why JavaScript? Relevant and challenging Rank of top languages on GitHub over time 2 (Source: GitHub.com)
Why JavaScript? Relevant and challenging 1096 pages 153 pages 3
Motivation: JavaScript (In)Security JavaScript: Popular beyond the browser Client-side web app Browser Operating system 4
Motivation: JavaScript (In)Security JavaScript: Popular beyond the browser Client-side Server-side or Mobile web app desktop app app Browser Node.js Dalvik VM Operating Operating Operating system system system 4
Motivation: JavaScript (In)Security JavaScript: Popular beyond the browser Sandbox Sandbox Client-side Server-side or Mobile web app desktop app app Browser Node.js Dalvik VM Operating Operating Operating system system system 4
Motivation: JavaScript (In)Security JavaScript: Popular beyond the browser Sandbox No sandbox! Sandbox Client-side Server-side or Mobile web app desktop app app Browser Node.js Dalvik VM Operating Operating Operating system system system 4
Culture of Naive Reuse Node.js code: Builds on 3rd-party code � Over 300.000 modules � No specified trust relationships between modules � Many indirect dependences 5
Culture of Naive Reuse Node.js code: Builds on 3rd-party code � Over 300.000 modules � No specified trust relationships between modules � Many indirect dependences Risk of vulnerable and malicious code 5
Real Example: Growl Module var msg = /* receive from network */ growl(msg); 6
Real Example: Growl Module var msg = /* receive from network */ growl(msg); Growl module: � Platform-specific command to show notifications � Pass message to command without any checks 6
Running Example function backupFile(name , ext) { var cmd = []; cmd.push("cp"); cmd.push(name + "." + ext); cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); var kind = (ext === "jpg") ? "pics" : "other"; console.log(eval("messages.backup_" + kind )); } 7
Running Example function backupFile(name , ext) { var cmd = []; Construct cmd.push("cp"); shell command cmd.push(name + "." + ext); cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); Execute it var kind = (ext === "jpg") ? "pics" : "other"; console.log(eval("messages.backup_" + kind )); } 7
Running Example function backupFile(name , ext) { var cmd = []; cmd.push("cp"); cmd.push(name + "." + ext); cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); var kind = (ext === "jpg") ? "pics" : "other"; console.log(eval("messages.backup_" + kind )); } Construct JavaScript code and execute it 7
Running Example function backupFile(name , ext) { var cmd = []; cmd.push("cp"); Injection APIs: cmd.push(name + "." + ext); Interpret string cmd.push("˜/. localBackup/"); as code exec(cmd.join(" ")); var kind = (ext === "jpg") ? "pics" : "other"; console.log(eval("messages.backup_" + kind )); } 7
Running Example function backupFile(name , ext) { var cmd = []; cmd.push("cp"); cmd.push(name + "." + ext); cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); var kind = (ext === "jpg") ? "pics" : "other"; console.log(eval("messages.backup_" + kind )); } Injection attack: backupFile("-h && rm -rf * && echo ", "") 7
Our Contributions 1. Study of injection vulnerabilities � First large-scale study of Node.js security � 236K modules, 816M lines of JavaScript 2. Repair of vulnerabilities � Static analysis and runtime enforcement � Automatic and easy to deploy � Small overhead and high accuracy 8
Our Contributions 1. Study of injection vulnerabilities � First large-scale study of Node.js security � 236K modules, 816M lines of JavaScript 2. Repair of vulnerabilities � Static analysis and runtime enforcement � Automatic and easy to deploy � Small overhead and high accuracy 8
Study: Prevalence Are injection vulnerabilities widespread? 9
Study: Prevalence Are injection vulnerabilities widespread? 9
Study: Prevalence Are injection vulnerabilities widespread? Direct uses 9
Study: Prevalence Are injection vulnerabilities widespread? Indirect uses via other modules 9
Study: Prevalence Are injection vulnerabilities widespread? Manual inspection of 150 call sites � Attacker-controlled data may reach API: 58% � Defense mechanisms � None: 90% � Regular expression: 9% 9
Study: Developer Reactions Do developers fix vulnerabilities? � Reported 20 previously unknown vulnerabilities � After several months, only 3 fixed 10
Study: Developer Reactions Do developers fix vulnerabilities? � Reported 20 previously unknown vulnerabilities � After several months, only 3 fixed 10
Study: Developer Reactions Do developers fix vulnerabilities? � Reported 20 previously unknown vulnerabilities � After several months, only 3 fixed Need mitigation technique that requires very little developer attention 10
Our Contributions 1. Study of injection vulnerabilities � First large-scale study of Node.js security � 236K modules, 816M lines of JavaScript 2. Repair of vulnerabilities � Static analysis and runtime enforcement � Automatic and easy to deploy � Small overhead and high accuracy 11
Our Contributions 1. Study of injection vulnerabilities � First large-scale study of Node.js security � 236K modules, 816M lines of JavaScript 2. Repair of vulnerabilities � Static analysis and runtime enforcement � Automatic and easy to deploy � Small overhead and high accuracy 11
Preventing Injections Vulnerable code Static analysis String Statically templates safe code Synthesize policy Code with runtime checks Safe Runtime Dynamic enforcement runtime inputs behavior 12
Static Analysis: Template Trees 1. Backward data flow analysis � Overapproximate strings passed to injection API � Represent possible values as a tree 13
Static Analysis: Template Trees 1. Backward data flow analysis � Overapproximate strings passed to injection API � Represent possible values as a tree function backupFile(name , ext) { var cmd = []; cmd.push("cp"); cmd.push(name + "." + ext); cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); } 13
Static Analysis: Template Trees 1. Backward data flow analysis � Overapproximate strings passed to injection API � Represent possible values as a tree function backupFile(name , ext) { var cmd = []; join cmd.push("cp"); ” ” $cmd cmd.push(name + "." + ext); cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); } 13
Static Analysis: Template Trees 1. Backward data flow analysis � Overapproximate strings passed to injection API � Represent possible values as a tree function backupFile(name , ext) { var cmd = []; join cmd.push("cp"); push ” ” cmd.push(name + "." + ext); ”˜/.localBackup/” $cmd cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); } 13
Static Analysis: Template Trees 1. Backward data flow analysis � Overapproximate strings passed to injection API � Represent possible values as a tree function backupFile(name , ext) { var cmd = []; join cmd.push("cp"); push ” ” cmd.push(name + "." + ext); push ”˜/.localBackup/” cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); + $cmd } ”.” $name $ext 13
Static Analysis: Template Trees 1. Backward data flow analysis � Overapproximate strings passed to injection API � Represent possible values as a tree function backupFile(name , ext) { var cmd = []; join cmd.push("cp"); push ” ” cmd.push(name + "." + ext); push ”˜/.localBackup/” cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); + push } ”cp” ”.” $cmd $name $ext 13
Static Analysis: Template Trees 1. Backward data flow analysis � Overapproximate strings passed to injection API � Represent possible values as a tree function backupFile(name , ext) { var cmd = []; join cmd.push("cp"); push ” ” cmd.push(name + "." + ext); push ”˜/.localBackup/” cmd.push("˜/. localBackup/"); exec(cmd.join(" ")); + push } empty ”cp” ”.” $name $ext array 13
Static Analysis: Templates 2. Evaluate template trees into templates � Statically model operations (bottom-up) � Unknown parts to be filled at runtime 14
Recommend
More recommend