Giter Club home page Giter Club logo

fuzzing's Introduction

build

The goal of this workshop is to use fuzzing to test a tool called marqdown, which takes a markdown file, and generates a html rendering of a survey:

See marqdown in use at checkbox.io.

Fuzzing

Fuzzing is a random testing techique. Fuzzing can be divided into "black-box" (dumb) and "white-box" (smart) approaches. In this workshop, we focus on "black-box" fuzzing. Generally, black-box fuzzing can be implemented in two ways:

  1. generative: test input is randomly created. Generation can be guided by grammars or other domain knowledge. This approach is commonly used for security testing.
  2. mutation: test input is randomly modified. The test input can be existing templates, input files, or captured network traffic that is replayed. Imagine you were testing Microsoft Word and you had a 200 page document. If you randomly made changes to the document and attempted to open it with Word—chances are you might be able to discover a bug.

Setup

Clone this repository and run npm install.

We will be using a mutation approach in this workshop. To assist, two files have been provided, simple.md, and test.md, which are markdown files read by the program.

Running node main.js will output:

passed 1000, failed 0, reduced 0

The program is simply reading an input file and for a 1000 times

  • asking a fuzzer to randomly change the string
  • passing the fuzzed input to marqdown and simply checking for exceptions being thrown (our test oracle):
    var markDown = fs.readFileSync('test.md','utf-8');
    //var markDown = fs.readFileSync('simple.md','utf-8');

    for (var i = 0; i < 1000; i++) {

        var mutuatedString = fuzzer.mutate.string(markDown);

        try
        {
            marqdown.render(mutuatedString);
            passedTests++;
        }
        catch(e)
        {
            failedTests.push( {input:mutuatedString, stack: e.stack} );
        }
    }

But the fuzzer right now is just returning the same string!

Generating Fuzzed Input Files

Now, we need to generate mutations to the input file in order to discover failures. Add the following functionality:

  1. With 5% chance, reverse the input string.

  2. Alternate between templates (simple.md/test.md)

  3. With 25% chance, remove a random set of characters, from a random start position: HINT: See Array.splice HINT: See fuzzer.random.integer(0,99) for creating a random number between 0-99.

  4. With a 25% chance, insert random characters into the string HINT: See insert array into another HINT: See fuzzer.random.string(10) for creating a random string of length 10.

  5. With a 5% chance, repeat. HINT: do/while

See random-js for tips on using some helpful random utilities.

// for example, this will execute true for 5% of evaluations.
if( fuzzer.random.bool(0.05) )

Minification

Fuzzing may create many inputs that are exercising the same bug. A test suite minification step will attempt to discard test cases that are not any more effective. Use stack trace to help determine if you are triggering the same bug, then only save the minimum tests needed (Inside reducedTests).

Reports

Now that you've generated some failing test cases, what can you do?

In a continuous deployment pipeline you could add a fuzzing component on new commits, and then reject them if you can generate failures. You might then generate a report, such as this:

Example Report:

The following commit: "Add new JSON5 parser" failed with the following exception. See attached test case.

SyntaxError: Expected ':' instead of '' JSON5.parse.error
    at JSON5.parse.error (/Users/gameweld/workshops/Fuzzing/node_modules/json5/lib/json5.js:50:25)
    at JSON5.parse.next (/Users/gameweld/workshops/Fuzzing/node_modules/json5/lib/json5.js:62:17)
    at JSON5.parse.object (/Users/gameweld/workshops/Fuzzing/node_modules/json5/lib/json5.js:443:21)
    at JSON5.parse.value (/Users/gameweld/workshops/Fuzzing/node_modules/json5/lib/json5.js:467:20)
    at Object.parse (/Users/gameweld/workshops/Fuzzing/node_modules/json5/lib/json5.js:491:18)
    at ProcessTokens (/Users/gameweld/workshops/Fuzzing/marqdown.js:287:22)
    at Object.exports.render (/Users/gameweld/workshops/Fuzzing/marqdown.js:25:18)
    at mutationTesting (/Users/gameweld/workshops/Fuzzing/main.js:60:22)
    at Object.<anonymous> (/Users/gameweld/workshops/Fuzzing/main.js:84:1)
    at Module._compile (module.js:460:26)

Bonus

Consider a generative approach based on the grammar of markdown.

  • Headers
  • Lists
  • Inline HTML
  • etc.

fuzzing's People

Contributors

chrisparnin avatar

Watchers

James Cloos avatar Tanmay Goel avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.