CI Integration
We recommend running Mayhem for API as part of your CI pipelines. Adding the fuzzer should take only a few minutes. Running the fuzzer as part of your continuous build will automatically check your API with your latest changes before they are merged and deployed.
Downloading the CLI
The first step is to download the CLI. We recommend using the latest
url to
always get the latest release. We aim to retain backwards compatibility for
command line arguments so that your build always works.
Assuming your build is running in Docker, we recommend adding the following lines to add the CLI to your Docker image:
ADD https://mayhem4api.forallsecure.com/downloads/cli/latest/linux-musl/mapi /usr/bin/mapi
RUN chmod 0755 /usr/bin/mapi
This ensures that you get the latest release every time, without affecting the Docker build cache for follow on layers if there hasn't been a new release. This will download the CLI (~25MB) every time you build the image. We recommend adding the line near the end of your build, shortly before you add your code, to minimize the number of uncached layers to rebuild when there is a new CLI release.
Optionally, to avoid re-downloading the CLI every time, we recommend using Docker's BuildKit. BuildKit checks the URL to see if a new version is available, and only downloads it if necessary. This ensures you get the latest release at all times without slowing down your builds with unnecessary downloads. Enable BuildKit with a simple environment variable:
$ DOCKER_BUILDKIT=1 docker build .
Finally, if you happen to use Docker's experimental syntax, you can download the CLI in one command:
ADD --chmod=755 https://mayhem4api.forallsecure.com/downloads/cli/latest/macos/mapi /usr/bin/mapi
Authentication
The CLI requires a token to function. We recommend storing your mapi token in
your CI secret stores, and loading it in the MAPI_TOKEN
environment
variable. The CLI will use the value in that environment variable
automatically.
Running the fuzzer
To fuzz your API, you'll have to first start your API locally following our best practices. Once it's up and running, invoke the fuzzer with:
mapi run <target> <duration> <spec-file> --url <url> --junit results.xml
<target>
is the name of your api target that you created withmapi target create
. The target name is often the name of your project.<duration>
depends on how long you want your build to take. We recommendauto
, but you may specify a fixed duration such as60sec
instead. To maximize fuzzing duration without slowing down the build, we recommend fuzzing in parallel to other build steps, for the duration of those build steps.- If your API requires authentication for some endpoints, consider passing it to the fuzzer for best results.
Note that --url
and --junit
options are optional. If --url
is
unspecified, it will come from the URL you specified in the API target.
--junit
is only necessary if you want your CI to parse a JUnit XML to extract
the tests and potential failures (see below).
Gathering the results
The CLI will return an error code if any 500 responses are observed. This can
be used to fail the build if you so choose. In addition, with the --junit
option, the fuzzer will output a JUnit XML file that your CI can parse.
The JUnit will contain a sample request/response for any endpoint that returned a 500, which can be helpful to debug the issue (especially if the API is run in debug mode and the response contains debugging output like stacktraces).
To get a human-friendly report that you can save as a build artifact, use the --html
option
to get a report like the following:
Ignoring Errors
You may filter out certain types of response errors that you do not want to appear in
your results using the CLI. For example to prevent 500 Internal Server Error responses
from being marked as issues, include the --ignore-rule InternalServerError
flag in your
call to mapi run
.
The --ignore-rule
flag may be used multiple times to ignore more than one type
of error. By default, ALL detected response errors will be classified as issues.
mapi run <target> <duration> <url> --ignore-rule InternalServerError
💡 To see a full list of
--ignore-rule
options, see the output ofmapi run --help
.