Skip to content

yonjah/funzz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Funzz

npm version Build Status codecov Known Vulnerabilities License Greenkeeper badge

Automatic fuzzer for hapi.js

Warning this is a proof of concept and is currently a work in progress. It is mostly used by me to automatically add fuzzing to my hapi test suites so stability and accuracy though important is not a major factor.

Usage

slides from SecTalks meetup about funzz

Funzz should work with any testing framework that exposes a describe and it methods. Like mocha -

const Hapi = require('@hapi/hapi');
const Funzz = require('funzz');

const server = Hapi.server();
server.route({ method: 'GET', path: '/test', handler: () => 'ok' });
Funzz(server);

Or Lab -

const Hapi = require('@hapi/hapi');
const Funzz = require('funzz');
const Lab = require('lab');

const { describe, it } = exports.lab = Lab.script();

const server = Hapi.server();
server.route({ method: 'GET', path: '/test', handler: () => 'ok' });
Funzz(server, { it, describe });

Or you can even try and see that no secrets are leaked in the result. Here is a naive example making making sure secret is never leaked -

const Hapi = require('@hapi/hapi');
const Funzz = require('funzz');
const Joi = require('@hapi/joi');
const Lab = require('@hapi/lab');

const { describe, it } = exports.lab = Lab.script();
const secret = Math.random().toString(32); //value that should not be leaked

const server = Hapi.server();
const code = '007';

server.route({
    method: 'GET',
    path: '/guess/{code}',
    handler(req, res) {

        if (req.params.code === code) {
            return secret;
        }

        return Math.random().toString(32);
    },
    config: {
        validate: {
            params: {
                code: Joi.string().regex(/\d{3}/)
            }
        }
    }
});

Funzz(server, {
    it,
    describe,
    permutations: 2500,
    validResponse: Joi.object({
        statusCode: Joi.number().integer().less(500),
        payload: Joi.string().regex(new RegExp(secret), { name: 'secret', invert: true }) // make sure secret value is never leaked in  response payload
    }).unknown()
});

Verifying tests

Funzz is still a work in progress so you might want to be sure it actually manages to pass your route validations otherwise fuzzing will not have much effect

On the first couple of runs you should set the option validateData to true so Funzz will try to verify if the data generated for the schema is indeed a valid data that should pass your route validation.

API

Funzz(server, [options]) => Array

Generate automatic tests for your hapi server routes returns array of all fuzzed data records

server - hapi server. all routes should be ready

but you don't have to call server.start

options - object with optional options

automate: automate the test if set to false will only return records array but will not actually run the test default(true),

routeMatcher: RegExp to match against route path. only matching routes will be included default(undefined)

validateData: if true will use the validation schema to assert the data and will throw an error if data is not valid default(false),

permutations: how many records to create for each route default(10),

validResponse: Joi schema to validate the response default(Joi.object({ statusCode: Joi.number().integer().less(500) }).unknown())

juzzOptions: Options to be passed directly to Juzz default({})

state: Object('cookie_name': Joi.schema) | null state cookies to be fuzzed when no cookie validation was set on route. By default when no specific cookie validation was set to route a fuzzing will be created as a string value to all cookies that were defined by server.state. Set to null to not inject any cookies or to object where key: schema to inject specific cookies.

usePayloads: array of payloads to be loaded from assets Fuzz db files ['all', 'string.all', 'file.all', 'string.generic', 'string.sql', 'string.javascript', string.noSql', 'string.JSON', 'string.XSS', 'string.URI', 'string.userAgent', 'file.image', 'file.zip'] default([])

payloadsProbability: Probability in percents to replace a payload 100 will replace all payloads, 0 will replace none default(100)

regexPayloadsAttempts: if rule is a regular expression pattern try to find a payload that matches it default(10)

injectReplace: function to allow you manipulate data before it is injected to the server default((record, data) => data)

it: test suite it function required when automate is true default(global.it),

describe: test suite describe function required when automate is true default(global.describe)

Funzz.inject(server, record, replace) => Promise

Inject a specific record into the server

Funzz.generateRoute(server, route, options) => Array

Create a list of injectable records for specific route

options - see Funzz method options with the exception that automate will default to false

Known issues

Funzz is mostly a small wrapper around Juzz. Juzz is still very unstable. if you have any issues where Funzz fail to generate a valid schema that will pass the route validation, or if it is not reaching all available data nodes it is most likely an issue with Juzz

Assets Attributions

This library is using payloads taken from SecLists (all sits in ./assets path) For Specific attribution see SecLists CONTRIBUTORS.md

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published