Fuzzing npm/nodejs 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 fuzzer for javascript/nodejs 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), my next publics trainings will be in:

  • 29 March – 01 April 2020 / ๐Ÿ‡ธ๐Ÿ‡ฌย Singapore ==> SHACK/WhiskeyCon.
  • 20 – 22 April 2020 / ๐Ÿ‡ณ๐Ÿ‡ฑ Amsterdam ==> HITB.
  • 15 – 18 June 2020 / ๐Ÿ‡จ๐Ÿ‡ฆ Montreal ==> REcon.
  • 01 – 04 August 2020 / ๐Ÿ‡บ๐Ÿ‡ธ Las Vegas ==> Ringzer0.
  • Onsite trainings ==> here.

1. Fuzzer: Jsfuzz

Jsfuzz is a coverage-guided fuzzer for javascript/nodejs 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 fuzz 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 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 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), my next public trainings will be in:

  • 29 March – 01 April 2020 / ๐Ÿ‡ธ๐Ÿ‡ฌย Singapore ==> SHACK/WhiskeyCon.
  • 20 – 22 April 2020 / ๐Ÿ‡ณ๐Ÿ‡ฑ Amsterdam ==> HITB.
  • 15 – 18 June 2020 / ๐Ÿ‡จ๐Ÿ‡ฆ Montreal ==> REcon.
  • 01 – 04 August 2020 / ๐Ÿ‡บ๐Ÿ‡ธ Las Vegas ==> Ringzer0.
  • Onsite trainings ==> 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