Fuzzing javascript nodejs/npm WebAssembly parsing library with jsfuzz
I asked recently on twitter what should be my next blogpost subject and voters choose this one, so here it is.
In this short blogpost, I will first introduce jsfuzz, a coverage-guided javascript fuzzer for nodejs/npm packages. Then, I’ll discuss about the wasm binary parsing library I decided to target. Finally, I’ll explain how to create a jsfuzz target script and show the OOM/DoS crash I found.
Just a quick reminder before we start, if you are interested about WebAssembly security (both reversing and fuzzing), I decided to convert my 4-day live training into recorded courses.
More details about my courses here.
1. Javascript fuzzer: Jsfuzz
Jsfuzz is both user-friendly and efficient, especially when fuzzing parsing libraries. You will only need to implement the following function to start fuzzing your target. All the fuzzing/mutation logic, coverage collection and crash detection will be handle by jsfuzz.
2. Target: @webassemblyjs/wasm-parser
webassemblyjs is a set of 22 dedicated packages for WebAssembly module manipulation. Most of them are really popular npm package with more than 6 millions weekly downloads each, like those ones:
- @webassemblyjs/ast: AST utils for webassemblyjs
- @webassemblyjs/wasm-parser: WebAssembly binary format parser
- @webassemblyjs/wast-parser: WebAssembly text format parser
3. Setup the fuzzing javascript target script
The process to setup a fuzz target script with jsfuzz is extremely simple. The first step is to create a corpus of valid WebAssembly module like the ones on Mozilla github repository: MDN webassembly-examples.
Then, run the fuzzer with the following command:
jsfuzz fuzz-wasm-parser.js corpus-wasm
You should immediately trigger some valid error/exception and you will need to customized the fuzz target to catch and ignored them like in the following code (available here).
4. Result: OOM/DoS of javascript nodejs triggered
Once most common exceptions are handled using try/catch, jsfuzz will start to generate fuzzing status logs and eventually crash like the following picture.
This bug is triggered really quickly (less than a minute) by the fuzzer with my wasm module corpus.
I quickly minimized the crashing buffer, create a reproducer JS file and directly open an issue on webassemblyjs github repository.
In October 2019, Fuzzit team found another bug in this library but not in the same npm package: @webassemblyjs/wast-parser: Crash/TypeError.
5. Conclusion
I strongly invite every JavaScript/nodejs developer to give a try to Jsfuzz. It will help you when fuzzing npm package, finding bugs, create edge-cases inputs and easily get code coverage visibility. Kudos again to Fuzzit for sharing this fuzzer publicly.
Final reminder, If you want to learn/discover more about WebAssembly security (both reversing and fuzzing), I decided to convert my 4-day live training into recorded courses.
More details about my courses here.
If you want to contact me for consulting, please DM me on Twitter/LinkedIn or use the following contact form.
Patrick Ventuzelo / @Pat_Ventuzelo