adrianhesketh.com

OWASP baseline scan with basic auth in Docker and Github Actions

I was setting up a new site and wanted to run a baseline OWASP Zed Attack Proxy (ZAP) check on it as part of the CI pipeline.

There’s a Docker image for that at https://www.zaproxy.org/docs/docker/baseline-scan/ and a guide that shows how to use it to check APIs at https://www.zaproxy.org/blog/2017-06-19-scanning-apis-with-zap/

Rather than use it with APIs, I wanted to use it with a Website with basic authentication enabled because the feature branced versions of the site are protected by basic authentication.

Lots of ZAP documentation is about contexts and other UI related settings, but it’s possible to set basic authentication by using an Authorization header, and the API blog post has what looks like a working example. I had to read https://www.zaproxy.org/faq/how-do-you-find-out-what-key-to-use-to-set-a-config-value-on-the-command-line/ before I realised that the config I’d copy/pasted needed to be modified.

To calculate the value for the header, you can use the base64 command line tool.

echo "user:password" | base64

This gives the output:

dXNlcjpwYXNzd29yZAo=

This can then be added to an options file, after the “Basic " prefix.

options.prop

replacer.full_list(0).description=auth1
replacer.full_list(0).enabled=true
replacer.full_list(0).matchtype=REQ_HEADER
replacer.full_list(0).matchstr=Authorization
replacer.full_list(0).regex=false
replacer.full_list(0).replacement=Basic dXNlcjpwYXNzd29yZAo=

run.sh

The -v $(pwd):/zap/wrk/ part of the command mounts the current directory’s contents into the Docker container at /zap/wrk/, allowing it to read the options.prop file.

docker run -v $(pwd):/zap/wrk/ -t owasp/zap2docker-weekly zap-baseline.py \
    -t https://example.com/ \
    -z "-configfile /zap/wrk/options.prop"

Output

Lots of text like this…

PASS: X-AspNet-Version Response Header [10061]
PASS: PII Disclosure [10062]
PASS: Timestamp Disclosure [10096]
PASS: Cross-Domain Misconfiguration [10098]
PASS: Weak Authentication Method [10105]
PASS: Modern Web Application [10109]
PASS: Private IP Disclosure [2]
PASS: Session ID in URL Rewrite [3]
PASS: Script Passive Scan Rules [50001]
PASS: Insecure JSF ViewState [90001]
PASS: Charset Mismatch [90011]
PASS: Application Error Disclosure [90022]
PASS: Loosely Scoped Cookie [90033]

Github Action

With that in place, I was able to test locally. But I wanted to get it running as part of the CI pipeline. There’s a Github Action for that with some docs: https://www.zaproxy.org/blog/2020-04-09-automate-security-testing-with-zap-and-github-actions/

However, I couldn’t see in the documentation of the plugin how to set the -z parameter to set options, after I read the code I realised that I needed to pass it to the cmd_options setting and make sure that the file was in the repo. In the best traditions of YAML, it took me a few attempts to get the quote escaping right.

on: [push]

jobs:
  zap_scan:
    runs-on: ubuntu-latest
    name: Scan the webapplication
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          ref: master
      - name: ZAP Scan
        uses: zaproxy/action-baseline@v0.3.0
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          docker_name: 'owasp/zap2docker-stable'
          target: 'https://example.com'
          cmd_options: '-z "-configFile /zap/wrk/options.prop"'

With that in place, the Github Action started giving out the right issues.

The structure of the repo is:

I might move the options.prop file, but then I’d need to move the -configFile value.