- Fork the project template
- Create the fuzz targets
- Enable coverage-guided fuzz testing
- Run the fuzz test
- Fix the vulnerabilities
Tutorial: Perform fuzz testing in GitLab
Coverage-guided fuzz testing sends unexpected, malformed, or random data to your application, and then monitors your application for unstable behaviors and crashes.
This helps you discover bugs and potential security issues that other QA processes may miss.
You should use fuzz testing in addition to other security scanners and your own test processes. If you’re using GitLab CI/CD, you can run fuzz tests as part your CI/CD workflow.
To set up, configure, and perform coverage-guided fuzz testing using JavaScript in this tutorial, you:
- Fork the project template to create a project to run the fuzz tests in.
- Create the fuzz targets.
- Enable coverage-guided fuzz testing in your forked project.
- Run the fuzz test to identify security vulnerabilities.
- Fix any vulnerabilities identified by the fuzz test.
Fork the project template
First, to create a project to try out fuzz testing in, you must fork the fuzz-testing
project template:
- Open the
fuzz-testing
project template. - Fork the project template.
- When forking the project template:
- Name the forked project
fuzz-testing-demo
. - Select an appropriate namespace.
- Set project visibility to Private.
- Name the forked project
You have successfully forked the fuzz-testing
project template. Before you can
start fuzz testing, remove the relationship between the project template and the fork:
- On the left sidebar, select Settings > General.
- Expand Advanced.
- In the Remove fork relationship section, select Remove fork relationship. Enter the name of the project when prompted.
Your project is ready and you can now create the fuzz test. Next you will create the fuzz targets.
Create the fuzz targets
Now you have a project for fuzz testing, you create the fuzz targets. A fuzz target is a function or program that, given an input, makes a call to the application being tested.
In this tutorial, the fuzz targets call a function of the my-tools.js
file using
a random buffer as a parameter.
To create the two fuzz target files:
- On the left sidebar, select Search or go to and find the
fuzz-testing-demo
project. - Create a file in the root directory of the project.
-
Name the file
fuzz-sayhello.js
and add the following code:let tools = require('./my-tools') function fuzz(buf) { const text = buf.toString() tools.sayHello(text) } module.exports = { fuzz }
You can also copy this code from the
fuzz-testing-demo/fuzzers/fuzz-sayhello.js
project file. - Name the Target Branch
add-fuzz-test
and write a descriptive commit message.- Do not select the Start a new merge request with these changes checkbox yet.
- Select Commit changes.
- Return to the root directory of the project.
- Make sure you are in the
add-fuzz-test
branch. -
Create the second file named
fuzz-readme.js
and add the following code:let tools = require('./my-tools') function fuzz(buf) { const text = buf.toString() tools.readmeContent(text) } module.exports = { fuzz }
You can also copy this code from the
fuzz-testing-demo/fuzzers/fuzz-readme.js
project file. - Write a descriptive commit message.
- Make sure the Target Branch is
add-fuzz-test
. - Select Commit changes.
You now have two fuzz targets that can make calls to the application being tested. Next you will enable the fuzz testing.
Enable coverage-guided fuzz testing
To enable coverage-guided fuzz testing, create a CI/CD pipeline running
the gitlab-cov-fuzz
CLI to execute the fuzz test on the two fuzz targets.
To create the pipeline file:
- Make sure you are in the
add-fuzz-test
branch. - In the root directory of the
fuzz-testing-demo
project, create a new file. -
Name the file
.gitlab-ci.yml
and add the following code:default: image: node:18 stages: - fuzz include: - template: Coverage-Fuzzing.gitlab-ci.yml readme_fuzz_target: extends: .fuzz_base tags: [saas-linux-large-amd64] # Optional variables: COVFUZZ_ADDITIONAL_ARGS: '--fuzzTime=60' script: - npm config set @gitlab-org:registry https://gitlab.com/api/v4/packages/npm/ && npm i -g @gitlab-org/jsfuzz - ./gitlab-cov-fuzz run --engine jsfuzz -- fuzz-readme.js hello_fuzzing_target: extends: .fuzz_base tags: [saas-linux-large-amd64] # Optional variables: COVFUZZ_ADDITIONAL_ARGS: '--fuzzTime=60' script: - npm config set @gitlab-org:registry https://gitlab.com/api/v4/packages/npm/ && npm i -g @gitlab-org/jsfuzz - ./gitlab-cov-fuzz run --engine jsfuzz -- fuzz-sayhello.js
This step adds the following to your pipeline: - A
fuzz
stage using a template. - Two jobs,readme_fuzz_target
andhello_fuzzing_target
. Each job runs using thejsfuzz
engine, which reports unhandled exceptions as crashes.You can also copy this code from the
fuzz-testing-demo/fuzzers/fuzzers.yml
project file. - Write a descriptive commit message.
- Make sure the Target Branch is
add-fuzz-test
. - Select Commit changes.
You have successfully enabled coverage-guided fuzz testing. Next you will run the fuzz test using the pipeline you’ve just created.
Run the fuzz test
To run the fuzz test:
- On the left sidebar, select Code > Merge requests.
- Select New merge request.
- In the Source branch section, select the
add-fuzz-test
branch. - In the Target branch section, make sure that your namespace and the
main
branch are selected. - Select Compare branches and continue.
- Create the merge request.
Creating the merge request triggers a new pipeline, which runs the fuzz test. When the pipeline is finished running, you should see a security vulnerability alert on the merge request page.
To see more information on each vulnerability, select the individual Uncaught-exception links.
You have successfully run the fuzz test and identified vulnerabilities to fix.
Fix the vulnerabilities
The fuzz test identified two security vulnerabilities. To fix those
vulnerabilities, you use the my-tools.js
library.
To create the my-tools.js
file:
- Make sure you are in the
add-fuzz-test
branch of the project. - Go to the root directory of your project and open the
my-tools.js
file. -
Replace the contents of this file with the following code:
const fs = require('fs') function sayHello(name) { if(name.includes("z")) { //throw new Error("😡 error name: " + name) console.log("😡 error name: " + name) } else { return "😀 hello " + name } } function readmeContent(name) { let fileName = name => { if(name.includes("w")) { return "./README.txt" } else { return "./README.md" } } //const data = fs.readFileSync(fileName(name), 'utf8') try { const data = fs.readFileSync(fileName(name), 'utf8') return data } catch (err) { console.error(err.message) return "" } } module.exports = { sayHello, readmeContent }
You can also copy the code from the
fuzz-testing-demo/javascript/my-tools.js
project file. - Select Commit changes. This triggers another pipeline to run another fuzz test.
- When the pipeline is finished, check the merge request Overview page. You should see that the security scan detected no new potential vulnerabilities.
- Merge your changes.
Congratulations, you’ve successfully run a fuzz test and fixed the identified security vulnerabilities!
For more information, see coverage-guided fuzz testing.