debian-mirror-gitlab/doc/tutorials/fuzz_testing_tutorial.md

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

244 lines
8.4 KiB
Markdown
Raw Normal View History

2023-06-20 00:43:36 +05:30
---
stage: Secure
group: Dynamic Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Tutorial: Perform fuzz testing in GitLab **(ULTIMATE)**
[Coverage-guided fuzz testing](../user/application_security/coverage_fuzzing/index.md#coverage-guided-fuzz-testing-process) 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:
1. [Fork the project template](#fork-the-project-template) to create a project
to run the fuzz tests in.
1. [Create the fuzz targets](#create-the-fuzz-targets).
1. [Enable coverage-guided fuzz testing](#enable-coverage-guided-fuzz-testing)
in your forked project.
1. [Run the fuzz test](#run-the-fuzz-test) to identify security vulnerabilities.
1. [Fix any vulnerabilities](#fix-the-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:
1. Open the [`fuzz-testing` project template](https://gitlab.com/gitlab-org/tutorial-project-templates/fuzz-testing).
1. [Fork the project template](../user/project/repository/forking_workflow.md).
1. When forking the project template:
- Name the forked project `fuzz-testing-demo`.
- Select an appropriate [namespace](../user/namespace/index.md).
- Set [project visibility](../user/public_access.md) to **Private**.
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:
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. 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:
1. On the top bar, select **Main menu > Projects** and select the `fuzz-testing-demo` project.
1. Create a file in the root directory of the project.
1. Name the file `fuzz-sayhello.js` and add the following code:
```javascript
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.
1. 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.
1. Select **Commit changes**.
1. Return to the root directory of the project.
1. Make sure you are in the `add-fuzz-test` branch.
1. Create the second file named `fuzz-readme.js` and add the following code:
```javascript
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.
1. Write a descriptive commit message.
1. Make sure the **Target Branch** is `add-fuzz-test`.
1. 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:
1. Make sure you are in the `add-fuzz-test` branch.
1. In the root directory of the `fuzz-testing-demo` project, create a new file.
1. Name the file `.gitlab-ci.yml` and add the following code:
```yaml
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` and `hello_fuzzing_target`. Each job runs using
the `jsfuzz` engine, which reports unhandled exceptions as crashes.
You can also copy this code from the `fuzz-testing-demo/fuzzers/fuzzers.yml`
project file.
1. Write a descriptive commit message.
1. Make sure the **Target Branch** is `add-fuzz-test`.
1. 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:
1. On the left sidebar, select **Merge requests**.
1. Select **New merge request**.
1. In the **Source branch** section, select the `add-fuzz-test` branch.
1. In the **Target branch** section, make sure that your namespace and the `main` branch are selected.
1. Select **Compare branches and continue**.
1. [Create the merge request](../user/project/merge_requests/creating_merge_requests.md).
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:
1. Make sure you are in the `add-fuzz-test` branch of the project.
1. Go to the root directory of your project and open the `my-tools.js` file.
1. Replace the contents of this file with the following code:
```javascript
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.
1. Select **Commit changes**. This triggers another pipeline to run another fuzz test.
1. When the pipeline is finished, check the merge request **Overview** page. You
should see that the security scan detected no new potential vulnerabilities.
1. 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](../user/application_security/coverage_fuzzing/index.md).