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 a coverage-guided fuzzer for javascript node.js packages developped by Fuzzit. The typical bugs found by jsfuzz are unhandled exceptions, logic bugs, Denial-of-Service (DoS) caused by hangs and excessive memory usage (OOM).

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.

jsfuzz wasm npm nodejs package fuzzing
Minimal custom jsfuzz target script

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:

I decided to target @webassemblyjs/wasm-parser because the API is really simple and also because I think jsfuzz mutation algorithm will be more efficient on binary file.
wasm api webassembly api fuzzing npm
wasm-parser npm package simple API
wasm npm parser popular package fuzzing

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).

wasm fuzzer jsfuzz webassembly parser
wasm-parser complete fuzz target

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.

wasm npm parser crash reproducer webassembly fuzzing
Reproducer for DoS/OOM bugs found

In October 2019, Fuzzit team found another bug in this library but not in the same npm package: @webassemblyjs/wast-parser: Crash/TypeError.

jsfuzz crash nodejs npm package wasm webassembly
jsfuzz crash after less than a minute

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

Subscribe for updates.

Join us to be the first to receive our latest news, blog posts and upcoming training dates and much more...

Any questions about our services and trainings ?

Get in touch today with any questions that you might have.