This DoS Goes Loop-di-Loop
Allon Mureinik
Senior Manager, Seeker Node.js and .NET Agents
Synopsys, Inc.
allon.mureinik@synopsys.com / @mureinik / https://www.linkedin.com/in/mureinik/
FlawCon, 20/10/2019
© 2019 Synopsys, Inc. 2This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
Developers vs Hackers
How will an
unreasonable person
abuse it?
How will a
reasonable person
use it?
https://thenounproject.com/term/theater/17128
© 2019 Synopsys, Inc. 3This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
Quick Reminder: Node.js’ Event Loop
https://thenounproject.com/term/redo/62716
© 2019 Synopsys, Inc. 4This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
Benchmarks
https://www.tandemseven.com/blog/performance-java-vs-node/
© 2019 Synopsys, Inc. 5This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
Reminder: Denial of Service (DoS)
https://thenounproject.com/term/decline/373722
© 2019 Synopsys, Inc. 6This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
Regex DoS (ReDoS)
console.log('a'sttime');
let regex = new RegExp('^(a+)+$');
for (let i = 1; i < 100; ++i) {
const str = Array(i + 1).join('a') + 'b';
const before = new Date();
regex.test(str);
const after = new Date();
const time = after - before;
console.log(`${i}t${time}`);
}
© 2019 Synopsys, Inc. 7This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
Regex DoS (ReDoS) - results
0
50,000
100,000
150,000
200,000
250,000
300,000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 33 34 35
Time(ms)
As
© 2019 Synopsys, Inc. 8This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
https://thenounproject.com/term/alternative-route/2902159
•Check your regexes
–E.g., use safe-regex, vuln-regex-detector
•Don’t allow tainted input as regex
–Not always possible…
–If you must, sanitize it (again safe-regex etc.)
•Don’t allow tainted input to be evaluated by a dodgy regex
–Usually not possible…
–Use length limits
•Think about alternative solutions
–re2 isn’t vulnerable to ReDoS
–Use specific tools for specific needs (e.g., validator.js)
Regex DoS (ReDoS) - Remediation
© 2019 Synopsys, Inc. 9This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
JSON DoS
for (let i = 1024; i <= 1024 * 1024 ; i += 1024) {
const str = '"' + Array(i + 1).join('a') + '"';
const before = new Date();
for (let j = 1; j < 100; ++j) {
JSON.parse(str);
}
const after = new Date();
console.log(`${i}t${after-before}`);
}
© 2019 Synopsys, Inc. 10This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
JSON DoS - Results
-50
0
50
100
150
200
250
300
0 200 400 600 800 1000 1200
Time(ms)
String Lengh (KB)
© 2019 Synopsys, Inc. 11This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
https://thenounproject.com/term/alternative-route/2902159/
•Don’t allow tainted input to be parsed
–Not realistic…
•Limit the size of the input
–Express: app.use(express.json({limit: '50kb'})
–Hapi: route.options.payload.maxBytes = 50 * 1024
•If you aren’t parsing JSON by a middle, consider alternative
libraries like BFJ or JSONStream
JSON DoS - Remediation
© 2019 Synopsys, Inc. 12This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
“If anything can hang, it will”
- Murphy’s law of storage
Storage (I/O) DoS
© 2019 Synopsys, Inc. 13This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
The are two ways to perform storage operations in Node.js:
1. The async way
–Delegate a storage operation to the kernel, and wait for a callback
–E.g.: fs.readDir, fs.writeFile, etc
–3rd parties follow similar patterns (e.g., fs-extra, adm-zip)
2. The wrong way
Storage (I/O) DoS - Remediation
© 2019 Synopsys, Inc. 15This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0)
Questions?
https://thenounproject.com/term/questions/1195076/
Thank You
Contact
allon.mureinik@synopsys.com
@mureinik
https://www.linkedin.com/in/mureinik/

This DoS goes loop-di-loop

  • 1.
    This DoS GoesLoop-di-Loop Allon Mureinik Senior Manager, Seeker Node.js and .NET Agents Synopsys, Inc. allon.mureinik@synopsys.com / @mureinik / https://www.linkedin.com/in/mureinik/ FlawCon, 20/10/2019
  • 2.
    © 2019 Synopsys,Inc. 2This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) Developers vs Hackers How will an unreasonable person abuse it? How will a reasonable person use it? https://thenounproject.com/term/theater/17128
  • 3.
    © 2019 Synopsys,Inc. 3This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) Quick Reminder: Node.js’ Event Loop https://thenounproject.com/term/redo/62716
  • 4.
    © 2019 Synopsys,Inc. 4This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) Benchmarks https://www.tandemseven.com/blog/performance-java-vs-node/
  • 5.
    © 2019 Synopsys,Inc. 5This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) Reminder: Denial of Service (DoS) https://thenounproject.com/term/decline/373722
  • 6.
    © 2019 Synopsys,Inc. 6This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) Regex DoS (ReDoS) console.log('a'sttime'); let regex = new RegExp('^(a+)+$'); for (let i = 1; i < 100; ++i) { const str = Array(i + 1).join('a') + 'b'; const before = new Date(); regex.test(str); const after = new Date(); const time = after - before; console.log(`${i}t${time}`); }
  • 7.
    © 2019 Synopsys,Inc. 7This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) Regex DoS (ReDoS) - results 0 50,000 100,000 150,000 200,000 250,000 300,000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 33 34 35 Time(ms) As
  • 8.
    © 2019 Synopsys,Inc. 8This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) https://thenounproject.com/term/alternative-route/2902159 •Check your regexes –E.g., use safe-regex, vuln-regex-detector •Don’t allow tainted input as regex –Not always possible… –If you must, sanitize it (again safe-regex etc.) •Don’t allow tainted input to be evaluated by a dodgy regex –Usually not possible… –Use length limits •Think about alternative solutions –re2 isn’t vulnerable to ReDoS –Use specific tools for specific needs (e.g., validator.js) Regex DoS (ReDoS) - Remediation
  • 9.
    © 2019 Synopsys,Inc. 9This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) JSON DoS for (let i = 1024; i <= 1024 * 1024 ; i += 1024) { const str = '"' + Array(i + 1).join('a') + '"'; const before = new Date(); for (let j = 1; j < 100; ++j) { JSON.parse(str); } const after = new Date(); console.log(`${i}t${after-before}`); }
  • 10.
    © 2019 Synopsys,Inc. 10This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) JSON DoS - Results -50 0 50 100 150 200 250 300 0 200 400 600 800 1000 1200 Time(ms) String Lengh (KB)
  • 11.
    © 2019 Synopsys,Inc. 11This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) https://thenounproject.com/term/alternative-route/2902159/ •Don’t allow tainted input to be parsed –Not realistic… •Limit the size of the input –Express: app.use(express.json({limit: '50kb'}) –Hapi: route.options.payload.maxBytes = 50 * 1024 •If you aren’t parsing JSON by a middle, consider alternative libraries like BFJ or JSONStream JSON DoS - Remediation
  • 12.
    © 2019 Synopsys,Inc. 12This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) “If anything can hang, it will” - Murphy’s law of storage Storage (I/O) DoS
  • 13.
    © 2019 Synopsys,Inc. 13This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) The are two ways to perform storage operations in Node.js: 1. The async way –Delegate a storage operation to the kernel, and wait for a callback –E.g.: fs.readDir, fs.writeFile, etc –3rd parties follow similar patterns (e.g., fs-extra, adm-zip) 2. The wrong way Storage (I/O) DoS - Remediation
  • 14.
    © 2019 Synopsys,Inc. 15This DoS Goes Loop-di-Loop (Allon Mureinik, FlawCon 2019, cc-by-sa-4.0) Questions? https://thenounproject.com/term/questions/1195076/
  • 15.