• Stars
    star
    127
  • Rank 282,790 (Top 6 %)
  • Language
    TypeScript
  • License
    Other
  • Created almost 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An AFL-inspired genetic fuzz tester for JavaScript

js-fuzz

This is still very much a work in progress and is probably not suitable for "real" use yet!

js-fuzz is an American Fuzzy Lop-inspired fuzz tester for JavaScript code. It provides coverage-driven analysis and minimization while being fast and extraordinarily simple to use.

Example

This program tests that all valid JSON strings can be parsed with JSON5:

const JSON5 = require('json5')

exports.fuzz = input => {
  input = input.toString('utf8') // we give you buffers by default

  let isPlainJSON = true
  let isJSON5 = true
  try { JSON.parse(input) } catch () { isPlainJSON = false }
  try { JSON5.parse(input) } catch () { isJSON5 = false }

  // We catch and thrown errors and mark them as failures
  if (isPlainJSON && !isJSON5) {
    throw new Error('Found a string that was JSON but not JSON5');
  }

  return isPlainJSON ? 1 : 0
}

Usage

js-fuzz myFile.js

Usage is quite similar to go-fuzz. You should give the js-fuzz tool the path to a module that exports a fuzz function. This function will be called with an input Buffer, and should return:

  • -1 if that input should not be fed back into the fuzzer, even if it gives us better coverage
  • 1 if the fuzzer should increase the priority of the given input
  • 0 to let the fuzzer decide

In the above example, we asked to increase the priority of strings that can be parsed as plain JSON, since we want more of that sort of thing in order to test against JSON5. You can also return Promises from the fuzz function, or take a callback.

exports.fuzz = input => {
  return doSomethingAsync(input)
    .then(out => anotherThing())
    .then(valid => valid ? 1 : 0)
}

// or

exports.fuzz = (input, callback) => {
  myNodeStyleThing(input, err => {
    if (err) {
      callback(err)
    } else {
      callback(null, 1)
    }
  })
}

The fuzzer will run until you terminate it, reporting stats in your terminal, and will write output in the form of text files into a fuzz-output directory in your current working directory. You'll probably be most interested in ./fuzz-output/crashers, which will contain all inputs that caused an error in your program!

js-fuzz does assume that your program's behaviour is deterministic and that the fuzz function is pure. It will work when this does not hold true, but it will be less efficient at discovering code paths and edge cases.

Internals

The runner spawns child processes which execute the given input module, by default spawning one child per CPU core. We use Esprima and Escodegen to provide branch coverage on JavaScript code using a require hook. The coverage that's injected has little performance impact; running a benchmark on Douglas Crockford's JSON implementation, it's about a 0.6% overhead. Most of the mechanics are based heavily on the AFL whitepaper.

Limitations

Most limitations revolve around what Node will let us get at without leaning on native extensions, which I would prefer to avoid for maintainability and compatibility reasons.

  • This doesn't currently work in browsers, though I want it to do so in the future.
  • We don't have any coverage analysis for native extensions and I am not planning on adding it (though I am open to PRs).
  • This implementation is bounded, at least in simple programs by memory throughput; much copying and moving has to be done as slave processes serialize and unserialize data with communicating with the master. Outside of writing native bindings I am unsure how this problem could be addressed.
  • We aren't always able to collect coverage statistics for tasks which time out. While we still record the input, we aren't able to dedupe test cases.

Acknowledgments

  • The AFL project is the original fuzzer and is where most of the beautiful mechanics originated from.
  • Many mechanics in this implementation are derived from go-fuzz, which was also my original introduction to fuzzing. Dmitry talks through some of the internals here.

More Repositories

1

cockatiel

🐦 A resilience and transient-fault-handling library that allows developers to express policies such as Backoff, Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback. Inspired by .NET Polly.
TypeScript
1,355
star
2

blake3

BLAKE3 hashing for JavaScript: native Node bindings (where available) and WebAssembly
TypeScript
154
star
3

validity

Golang package for beautiful data validation
Go
39
star
4

sio

Socket.io CLI client and debugging tool.
JavaScript
26
star
5

matcha

A caffeine driven, simple command line for benchmarking
TypeScript
21
star
6

laravel-dbsim

Query builder sim for L4
JavaScript
20
star
7

multicraft

Revised UI for the next Multicraft panel
PHP
14
star
8

codesong

Fork of Dayle Rees's Earthsong theme with improvements for VS Code
13
star
9

msft-rewards-modeller

Modeller tool for Microsoft employees to figure out their compension
Jupyter Notebook
11
star
10

nodejs-testing

VS Code integration for node:test native tests
TypeScript
8
star
11

vscode-css-theme-completions

TypeScript
7
star
12

kap-azure

Azure Storage plugin for Kap
TypeScript
7
star
13

social-colors

LESS file with social media colors. Tired of looking them up. Every. Single. Time.
CSS
7
star
14

esbuild-problem-matchers

Problem matchers for esbuild tasks in VS Code
5
star
15

bump-module

JavaScript
4
star
16

vsix-viewer

TypeScript
4
star
17

vscode-webview-tools

Miscellaneous tools for building things in VS Code webviews
TypeScript
4
star
18

chromehash

A Rust/WebAssembly implementation of the Chrome content hashing algorithm
JavaScript
3
star
19

hosting-sim-2014

IT'S SO INTENSE BRAH
Ruby
3
star
20

-sv

👏 separated values
JavaScript
3
star
21

cosmonaut

Azure Cosmos DB ODM
TypeScript
3
star
22

gulp-breakout

Better breakout build environment for web development
JavaScript
3
star
23

peet-io

My new personal site, now with 100% more blog!
TypeScript
2
star
24

solarized-slack

CSS for making the Slack interface solarized!
CSS
2
star
25

recipes

Food I make
Go
2
star
26

bin-vcs

Experimental + WIP: version control for binary files with a git-like CLI
Go
2
star
27

protobill

PHP
2
star
28

ketama

Node.js hash ring implementation using libketama-like hashing
TypeScript
2
star
29

mchostexposed

CSS
2
star
30

fsu-entrance

Entrance for FSU
Java
2
star
31

grunt-breakout

Breakout build environment for web development
JavaScript
2
star
32

peet.io

Simple site for peet.io
JavaScript
2
star
33

typed-vscode-contributions

[WIP] Strongly-typed runtime and generators for VS Code extensions
TypeScript
1
star
34

dfa

Simple renderer for deterministic finite automatons
Go
1
star
35

CSC148-assignment-1

Python
1
star
36

centroid-api

API Wrapper for the CentroidMedia API
JavaScript
1
star
37

WHMCS-Dwolla-Gateway

Gateway for WHMCS into Dwolla.
PHP
1
star
38

kiln-monitor

A nice UI for monitoring Bartell kilns
C#
1
star
39

sixgood

Image sharing system for s.ix.gd
Python
1
star
40

rpt

Helper to measure how often things happen.
Go
1
star
41

backer

GPL Node.js-powered backup daemon.
CoffeeScript
1
star
42

test-controller-migration-example

An example of a migration from the Test Explorer UI to native VS Code testing
TypeScript
1
star
43

faster-import-cost

Fast import code display for Javascript code
TypeScript
1
star
44

HubSub

Java
1
star
45

csc209

C
1
star
46

mopidy-azure

Azure storage extension for Mopidy
Python
1
star
47

OpenMCD

Open source, drop-in replacement for the Multicraft daemon.
Java
1
star