Introducing ZAP
OWASP ZAP is the world’s most popular web app scanner that now sees over 4 Million “Check for Updates” calls per month (up from 1 million just earlier this year).
It is free, open source, and used by people with a wide range of security experience, ranging from newcomers right up to experienced security professionals to get a better understanding of web application security posture. The way OWASP ZAP works is by attacking your web apps in a similar way to a malicious hacker, where it attacks your apps when they are running and shows you what attackers will be able to find when they attack your app.
The ZAP Desktop
ZAP was built for flexibility and adoption, and therefore it is possible to run it in a diversity of ways aligned with how you like to work:
- From the command line
- As a desktop application
- As a background daemon
In this blog post I’ll show you how to automate ZAP from the command line, and to set it up by using the ZAP desktop application. The ZAP desktop app allows you to see exactly what ZAP does, and to tune ZAP to handle your app as effectively as possible.
ZAP requires Java 8+ to run locally, but you can also run ZAP in Docker and access it via a browser using Webswing. We won’t dive into this setup here but you are welcome to reference the docs to get started.
Just note, if you use the docker option then you will need to make sure you start docker with the option to map a local drive so that you can access the file you are going to generate after you stop the docker image. On *nix systems the docker option is -v $(pwd):/zap/wrk/:rw
- on Windows you will need to replace $(pwd)
with the full path of a suitable directory.
The Automation Framework
The Automation Framework (AF) allows you to control ZAP with one yaml file. There are other ways to automate ZAP, but the AF is the recommended approach for most users.
You can create the yaml file in a text editor but it is also possible to create it using the ZAP desktop, as that allows you to test the plan as you go, that is the option we will use here.
Exploring your App Using the Spiders
The first thing to do is to explore your app.
Apps designed for humans are typically best explored by humans, but that’s not a good option for automation and eventually scale.
However we will start by doing a bit of manual exploration just to make sure we can connect to the app.
In the ZAP desktop click on the “Manual Explore” button.
In the next form fill in the URL of your target app, uncheck the “Enable HUD” box and click on “Launch Browser”.
A browser should be launched and display your target app - for the sake of this example we will be using Firefox, but Chrome should work as well, if that is the browser you have installed.
Now look at the Sites tree - you should see at least one URL from your target app, probably many more. In this case I’m using OWASP Juice Shop as my target.
Now we can see how well each of the 2 spiders handles our app.
Right click on the top node of your app in the Sites tree and select “Attack -> Spider…”
Then click “Start Scan"
This spider should run very quickly, and it will tell you how many URLs are found and how many were added to the Sites tree:
If your target app is a more traditional app, then this should be sufficient. However, if it is a more modern web app which makes heavy use of JavaScript then you will need to use the AJAX spider.
Right click on the top node of your app in the Sites tree and select “Attack -> AJAX Spider…”
Then click “Start Scan"
This spider will take longer as it launches browsers in order to click on UI elements. It will also tell you how many URLs it found:
Exploring your App by Importing API Definitions
If your app just defines an API then you will not be able to explore it either manually or using either of the ZAP spiders.
If you have an API definition then you can import that via the “Import” menu item. ZAP supports importing the following definitions:
- Open API
- GraphQL
- WSDL
- HAR
Defining a Context
You do not need to define a context if you are just using ZAP manually, but you do need to define one when using the Automation Framework. Luckily this is easy to do - just right click the top node of your app in the Sites tree and select “Include in Context -> New Context“
and optionally give it a meaningful name:
Creating a Plan in the Desktop
We’re now ready to create the plan.
First, you need to find the “Automation” tab. ZAP has lots of tabs so all but the most essential ones are hidden by default. Click on the green plus tab in the bottom panel and select “Automation”:
In the new Automation panel click the “New Plan…” button:
Select the context you defined above and then one of the following Profiles:
- Baseline - if you just want to passively scan your app and not attack it
- GraphQL - if you have a GraphQL API definition
- OpenAPI - if you have an OpenAPI / Swagger API definition
- SOAP - if you have a SOAP definition
- Full Scan - if you want to attack your app (and do not have an API definition)
A summary of your plan will now be displayed:
A plan can be much more flexible than these profiles, but they are the best option to use when you are getting started.
The Baseline and Full scans will include both the spider and the spiderAjax - you can remove one of them if you find it is not necessary. Do not remove both as then the plan will not explore your app at all!
If you want to import an API definition in addition to spidering then add the relevant job.
You can edit a plan in the ZAP desktop:
Double clicking on any job will bring up a dialog which will allow you to configure it
The “Add job…” button will allow you to add a job to the existing plan
The “Remove Job…” button will remove the selected job
The “Move Job Up” button will move the selected job up one place
The “Move Job Down” button will move the selected job down one place
Passive Scanning
ZAP will passively scan every request initiated by ZAP or proxied through it.
The profiles will all add two related jobs:
- passiveScan-config - this allows you to fine tune the passive scanner
- passiveScan-wait - the waits until all of the requests have been passively scanned, it should always be run after any jobs which explore your app
Active Scanning
The activeScan job runs the active scanner - this performs the actual attacks.
You should always include this job unless you only want to passively scan your app.
Double clicking on the job will allow you to fine tune the active scan rules.
Generating a Report
The report job not surprisingly has the task of generating a report - there are a variety of templates with different options for you to choose from. See https://www.zaproxy.org/docs/desktop/addons/report-generation/templates/ for the latest list with examples of each.
Authentication
Authentication is hard, and definitely out of scope for this blog post (but we will do our best to write a deep dive on this in the future). However, ZAP can handle pretty much any authentication mechanisms - more details on the ZAP website. And the good news is that you can test authentication handling in the ZAP desktop where you can see exactly what is going on, and when you create a plan using that context all of the authentication configuration will be imported into the plan.
Testing Your Plan Locally
You can run the authentication plan you have created in ZAP using the “Run Plan…” button.
You will then see the status of the jobs as the plan runs:
If any of the jobs fail then you can investigate them in the ZAP desktop.
However jobs may appear to succeed while still not doing what you expect.
Thats is why the AF supports job outcome tests - these tests can be added to any job and can do things like:
- Check any of the ZAP statistics
- Check is specific alerts are present of absent
- Check if specific URLs have been found and optionally check their content
Statistics tests are added by default to the spider jobs, but you can add more tests to any of the jobs using the “Add Test…” button (there’s also a “Remove Test…” button) and don’t forget that you can double click on any of the tests in the plan in order to edit them.
Running in CI/CD
You can run AF tests from the command line using a command like:
zap.sh -cmd -autorun plan.yaml
You can also run them in docker. If you are using the stable image then we recommend updating ZAP using a separate command:
docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable bash -c "zap.sh -cmd -addonupdate; zap.sh -cmd -autorun /zap/wrk/plan.yaml"
The $(pwd):/zap/wrk/:rw
part of the command maps your local CWD to the directory /zap/wrk
in the docker container.
If you use any scripts in your plan then you will need to make sure they are in or below your local CWD and change your plan so that they are referenced via the location they appear in the docker container (i.e. under /zap/wrk
).
OWASP ZAP + Jit Integration
While ZAP is an extremely powerful tool, it is very much a “point solution” and does not provide any scan scheduling, history or an online interface. Jit is a DevSecOps orchestration platform which integrates ZAP and other security tools. By using Jit you can have your ZAP findings available in an aggregated dashboard with the rest of your security tooling, and receive greater context for the overall security posture of your application.
Top comments (1)
Great post @sbennetts and work on OWASP ZAP!