Add AppSec to Your CircleCI Pipeline With the StackHawk Orb
Tags: security, devops, testing
Published: 2020-04-29 21:00:30


_When you check in a new web app vulnerability, do you get an alert and guidance on how to fix it? With the new StackHawk CircleCI Orb you can, and it’s easy._

The modern CI/CD environment bristles with automation. When you check in your code, an invisible army of robots goes to work linting, compiling, unit testing, and integrating your software.

These processes help us code _faster_ since you don’t have to spend time manually building and testing, and _better_ since you get quick feedback and guidance on code quality. Now you can add test-driven _security_ to your pipeline with StackHawk.

In this post, we will use the [StackHawk CircleCI Orb](https://circleci.com/orbs/registry/orb/stackhawk/stackhawk) to build an app, fire it up in a container, and scan it for vulnerabilities, all within the CircleCI build environment.
The Application

I will be building and scanning [Vulny Django](https://github.com/stackhawk/vuln_django_play). It’s a small web poll app that StackHawk’s Chief Security Officer, Scott Gerlach, built from the [Django tutorial](https://docs.djangoproject.com/en/3.0/intro/tutorial01/). We often use it to test scans and pipelines because it’s simple, quick to build, and it has a good set of routes and potential security flaws.

## The Orb

[CircleCI](https://circleci.com/orbs/) Orbs are a clever way to package complicated bits of code to make your pipeline configuration code clean and DRY. We recently launched our own orb, which makes it simple to weave scans into your pipeline. It exposes all the features of StackHawk, including the ability to scan any web app, find routes by spidering, parse an OpenAPI spec, and even probe GraphQL.

The orb provides two jobs, [hawkscan-remote](https://circleci.com/orbs/registry/orb/stackhawk/stackhawk#jobs-hawkscan-remote), and [hawkscan-local](https://circleci.com/orbs/registry/orb/stackhawk/stackhawk#jobs-hawkscan-local). Each has advantages, but one is generally better suited for remote scans, and the other is best for running a self-contained scan within the CircleCI build environment.

Let’s take a look at the two options.

### stackhawk/hawkscan-remote

This is the faster and simpler of the two scan jobs, but it requires a remote instance of your app to be up and running. This is great if you have an existing integration environment accessible to CircleCI. All you need is to add a valid `stackhawk.yml` configuration file to your source repository, and add your StackHawk API key as a [secret](https://circleci.com/docs/2.0/env-vars/#secrets-masking) environment variable `HAWK_API_KEY`.

Here’s an example CircleCI configuration to use the hawkscan-remote job:

```yaml
# .circleci/config.yml
orbs:
  stackhawk: stackhawk/stackhawk@x.y.z
version: 2.1
workflows:
  scan-remote:
    jobs:
      - stackhawk/hawkscan-remote
```

And here’s an example StackHawk configuration:

```yaml
# stackhawk.yml
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://example.com
  env: Development
```

### stackhawk/hawkscan-local

This job allows you to spin up your own ephemeral integration environment right in your CircleCI pipeline.

When hawkscan-local runs, it starts a build VM, checks out your source code, runs a series of steps you provide, and then launches a [stackhawk/hawkscan](https://hub.docker.com/r/stackhawk/hawkscan) container. In the steps you provide, you can launch local services or containers to be scanned, right there in the CircleCI cloud.

## Putting It All Together

We will use the second job, `stackhawk/hawkscan-local`, to demonstrate using the orb to run an integration test in your CircleCI pipeline. Let’s get started!

### Get a StackHawk API Key

Go to https://stackhawk.com to sign up. Create an account, and get an API key. Be sure to save a copy in a secure undisclosed location. You will need it later.

### Clone the Vulny Django Repository

Head over to https://github.com/stackhawk/vuln_django_play and fork our repository. You can also clone it and copy it up to Bitbucket if you like. The key is to have your own copy to play with, and to set up as a project in CircleCI.

Take a glance at the files in this repository.

```
├── .circleci/
│   └── config.yml
├── .gitlab-ci.yml
├── Dockerfile
├── README.md
├── nginx.default
├── src/
├── stackhawk-circleci.yml
├── stackhawk-gitlab.yml
├── stackhawk.yml
└── start-server.sh
```

The `src` directory contains the app itself. And the `Dockerfile` file will be used to build the app and containerize it. There are other files associated with other build systems, such as `.gitlab-ci.yml` for GitLab. For our purposes we will focus on these three files:

1. `stackhawk.yml` – The HawkScan configuration file
2. `stackhawk-circleci.yml` – An additional HawkScan configuration file that we’ll use to customize our scan for CircleCI
3. `.circleci/config.yml` – The CircleCI project configuration file

### Configure HawkScan

Check out the primary configuration file, `stackhawk.yml`. We use this project to test lots of command line and automation scenarios, so we put all of our common configs in here, such as authentication parameters (`app.authentication`), and scan depth (`hawk.spider`).

For my CircleCI pipeline, I wanted to customize a few of these parameters, so I created `stackhawk-circleci.yml` and put my overrides there. These will be merged on top of the main configuration file. Here’s the whole file:

```yaml
# stackhawk-circleci.yml
app:
  applicationId: ${APP_ID}
  host: http://vulny-django:8020
```

This will override the `app.applicationId` and `app.host` entries from the main configuration. I’ll be setting the `APP_ID` environment variable in the CircleCI build configuration below by using the `stackhawk/hawkscan-local` parameter, `app-id`.

### Configure CircleCI

Let’s look at the CircleCI build configuration file.

```yaml
# .circleci/config.yml
version: 2.1

orbs:
  stackhawk: stackhawk/stackhawk@1.0.1

workflows:
  build-and-scan:
    jobs:
      - stackhawk/hawkscan-local:
          configuration-files: ./stackhawk.yml ./stackhawk-circleci.yml
          docker-network: scan_net
          app-id: 685847dd-0a74-4f02-b4d2-53f2396c93ed
          steps:
            - run:
                name: Build Vulny Django
                command: docker build -t vulny_django:latest .
            - run:
                name: Run Vulny Django
                command: |
                  docker network create scan_net
                  docker run --detach --network scan_net --name vulny-django --rm vulny_django:latest
```

Here we pull in the orb as `stackhawk`, and use it in our simple workflow, `build-and-scan`. We define a single job in the workflow using the orb job, `stackhawk/hawkscan-local`. The orb has several optional parameters, and we use three of them.

1. `docker-network` tells hawkscan-local to start the dockerized scanner to run on a named bridge network called `scan_net`.
2. `app-id` sets the environment variable, `APP_ID`, that we use in `stackhawk-circleci.yml` above to dynamically set `app.applicationId` at runtime. Be sure to update this with your own app ID!
3. `steps` sends a series of job steps to the orb to run on the VM before the scan starts.

In our three job steps, we build the app, create a docker bridge network, `scan_net`, and start our new container on that network.

### Add your Vulny Django Project to CircleCI

Head over to [CircleCI](https://app.circleci.com/) and add your GitHub repo as a project in CircleCI. In your project settings, add your StackHawk API key as a [secret](https://circleci.com/docs/2.0/env-vars/#secrets-masking) environment variable, `HAWK_API_KEY`. This will automatically get picked up in the `stackhawk/hawkscan-local` job and used to send scan results to your StackHawk console.

### Run the Pipeline

Make a commit to your repo and push it to GitHub to trigger a pipeline run. Then watch the job run in the CircleCI console. Here’s what you should see.

![CircleCI Workflow Results](https://lh3.googleusercontent.com/jmmcqB6zbewvkMyCgeGWZJ3k1aPVVTNbp1td6CsBMf03cP9vq92v4Rjv_KIRIxq8TLoqYEEDqjXdhIdgmvzS-l2SgV4Jwzac80VXZNeoebNXZ9vqDJ3idbqRxVzVM4-LMP_IuJoA)

When the job is finished, check your scan results in the StackHawk console. You can go directly to it by copying and pasting the link at the bottom of the Run HawkScan step in CircleCI. It should look like this:

`View on StackHawk platform: https://app.stackhawk.com/scans/xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX`

After following that link to the StackHawk console, you should see scan results similar to this:

![StackHawk Scan Results](https://lh3.googleusercontent.com/Z3wPqkCUfXfSW7h61vsicz-TEyjvV-QWMPwbPF1WruXjhqtd8d5U96EpV0o3JB1F3pI-s7GDcakq0y6RYDOQoSyaKUVIiLfn2QBVm8ZfNGyQp_x2vDSIpXuJJxkObdSeU66qFQ28)

# 🦅 KAA-KAWW!!!

☝️ That feeling when your scan works. To experience it yourself, visit https://www.stackhawk.com to get signed up for our early access release. Get started on the command line with our helpful [Docs](https://docs.stackhawk.com/), and be sure to check out our [integration guides](https://docs.stackhawk.com/continuous-integration/) for other popular CI/CD platforms.

Thanks, and good night!

Originally posted at [stackhawk.com](https://www.stackhawk.com).