2

Jazzer.js Brings Effective Fuzzing to JavaScript (Open-Source)

 2 years ago
source link: https://www.code-intelligence.com/blog/jazzer.js
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Norbert Schneider 5 min read

Jazzer.js Brings Effective Fuzzing to JavaScript (Open-Source)

TL;DR Fuzzing JavaScript is easy now

In this post, we introduce you to our new open-source fuzzer for the JavaScript ecosystem, Jazzer.js

Jazzer.js is a coverage-guided, in-process fuzzer for the Node.js platform. It’s based on the experience we gathered developing its namesake Jazzer, our fuzzer for the JVM platform. Internally, Jazzer.js uses libFuzzer as a solid industry-standard engine and brings many of its instrumentation-powered mutation features to JavaScript. Even though the initial release is in an early stage of Jazzer.js, it provides comprehensive fuzzing capabilities for your JavaScript and Node.js projects.

MeetJazzer.js

What’s Under the Hood of Jazzer.js?

Besides providing a state of the art fuzzing engine, which is done by integrating libFuzzer as a solid basis, a main goal of Jazzer.js is to seamlessly integrate into the JavaScript development workflow, so that developers can use the tools they know and love for fuzzing.

The libFuzzer integration is realized by a native Node.js add-on, which handles the libFuzzer lifecycle and provides integration and feedback points for the fuzzer’s more high-level JavaScript code. Moreover, libFuzzer’s fuzzing logic is executed in the background and does not interfere with the normal JavaScript execution model. Hence fuzzing of synchronous and asynchronous functions is supported out of the box.

During fuzzing, Jazzer.js instruments loaded code to add coverage feedback mechanisms to it. This enables the fuzzer to detect when new code paths are reached and to further continue in that direction. It also adds feedback mechanisms to detect usage of parts of its fuzzing input, for example a comparison in an if-statement, to improve the performed mutations and reach even deeper code paths.

What Is libFuzzer?

libFuzzer is a C/C++ fuzzer and part of the LLVM Compiler Infrastructure. It was created by Google to overcome problems with existing fuzzers at the time. It tightly integrates coverage-guided fuzzer logic with available bug detectors, a.k.a. sanitizers. In this setup it provides the basic fuzzing logic, while Jazzer.js bridges the gap between its C/C++ APIs and the JavaScript runtime.

The following diagram shows an overview of the involved components and their interaction.

Jazzer.js-diagram-1

How to Fuzz JavaScript

After discussing the fundamentals of Jazzer.js let us now have a look at how to use it in a Node.js JavaScript project. Hence, we assume some familiarity with JavaScript and the Node.js ecosystem.

1. Add Jazzer.js Dependency to the Project

Jazzer.js is bundled as a Node.js package and can be added to projects like any other dependency. Precompiled versions of the native part of the fuzzer are available for all common platforms and downloaded automatically. If a used platform is not available, a dedicated compilation step is executed during installation. To add the Jazzer.js dependency to a Node.js project, execute the following command.

> npm install --save-dev @jazzer.js/core

2. Create a Fuzz Target

Jazzer.js requires an entry point for fuzzing, this is commonly referred to as fuzz target. A simple example of a file defining one is shown below.

// file: fuzzTarget.js
module.exports.fuzz = function (data) {
myAwesomeCode(data.toString());
};

A fuzz target needs to export a function called fuzz, which takes a Buffer parameter and executes the actual code that should be tested based on the fuzzing input. Please note that the code above is executed in a synchronous fashion. Asynchronous execution is also supported out of the box, as shown in the Jazzer.js promise example.

3. Start Fuzzing

Adding the Jazzer.js dependency to a project also adds the Node.js command jazzer, which can be used to directly start the fuzzer. You can invoke it via npx-specifying the fuzz target created in the last step.

> npx jazzer fuzzTarget

The fuzzer output will look similar to the one below from Jazzer’s string compare example.

INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2472745350
INFO: Loaded 1 modules (512 inline 8-bit counters): 512 [0x530fa90, 0x530fc90),
INFO: Loaded 1 PC tables (512 PCs): 512 [0x7fe8bc9a4010,0x7fe8bc9a6010),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED cov: 2 ft: 2 corp: 1/1b exec/s: 0 rss: 108Mb
#1331 NEW cov: 5 ft: 5 corp: 2/17b lim: 17 exec/s: 0 rss: 115Mb L: 16/16 MS: 4 CrossOver-InsertByte-ChangeByte-InsertRepeatedBytes-
#5692 NEW cov: 6 ft: 6 corp: 3/33b lim: 58 exec/s: 0 rss: 115Mb L: 16/16 MS: 1 CMP- DE: "Awesome "-
#42739 NEW cov: 7 ft: 7 corp: 4/49b lim: 421 exec/s: 0 rss: 126Mb L: 16/16 MS: 2 ChangeByte-CMP- DE: "Fuzzing"-
==158151== Uncaught Exception: Jazzer.js: Welcome to Awesome Fuzzing!
Error: Welcome to Awesome Fuzzing!
at module.exports.fuzz (/home/norbert/Code-Intelligence/jazzer.js/examples/string_compare/fuzz.js:33:11)
==158151== ERROR: libFuzzer: fuzz target exited
SUMMARY: libFuzzer: fuzz target exited
MS: 1 ChangeByte-; base unit: be159789fe80858724068c1aaa2d5ee7582e3db3
0x41,0x77,0x65,0x73,0x6f,0x6d,0x65,0x20,0x46,0x75,0x7a,0x7a,0x69,0x6e,0x67,0x21,
Awesome Fuzzing!
artifact_prefix='./'; Test unit written to ./crash-dd107abbf60f67c533ff7aecb116ce483fc4facf
Base64: QXdlc29tZSBGdXp6aW5nIQ==

Jazzer.js provides extensive documentation in its source code repository as well as many additional examples.

More Features Coming Soon

There are ideas aplenty. Some of the next features that are planned for Jazzer.js are a dedicated hooking framework to enable custom bug detectors, like the ones already very successfully used by Jazzer, e.g. SQL Injections, Remote Code Executions (RCEs), and XSS. Furthermore, Jazzer.js will receive a better test framework integration, to make fuzzing as easy as unit testing.

As you can see, there is great potential in Jazzer.js. Don’t miss any updates by giving the GitHub repository a star and subscribing to our JavaScript newsletter. Lastly, try out Jazzer.js with your own projects. We would love to get your feedback and ideas!

See Jazzer.js on Github


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK