ZAP provides automated security tests in continuous integration pipelines

Always On

Zapping from a Docker Container

The path of least resistance to getting started is by installing Docker on a host or virtual machine and running the ZAP Docker image as a container. Even inside complex environments, if you can open up TCP port 5900, you will be able to connect over VNC and get access to ZAP's GUI (firewalls permitting).

To get Docker installed successfully on a Debian derivative (I'm using Ubuntu on a server and Mint on a laptop) use the command

$ apt install docker.io

to install the package. You'll be glad to hear that even a cheap and cheerful AWS or Digital Ocean cloud instance will happily serve ZAP and its GUI on Docker. Some tests might take a bit longer, but certainly you won't be too put out by server specifications at first. However, you might want to up the RAM and CPU specs for CI integration. Sadly, sometimes 512MB of RAM even on Linux boxes doesn't get you very far these days if you want to run a feature-filled application.

Now it's time to drop the theory and move on to the juicy stuff. The lengthy Docker command shown below does a few things automatically and in a relatively sophisticated way:

$ docker run -u zap -p 5900:5900 -p 81:8080 -i owasp/zap2docker-stable x11vnc --forever --usepw --create

First, you can see that, from a security perspective, I'm running the Docker container application as user zap and not as root, which might help with some host security worries. Second, as mentioned before, TCP port 5900 is open to access ZAP's GUI over VNC, but you can choose an arbitrary port by adjusting the first 5900 to your preferred port. Third, because some applications (e.g., Kubernetes) need TCP port 8080, in this case, I've opened up TCP port 81 on my host, and not TCP port 8080. Finally, you might spot the mention of X11 and VNC, which, especially when you're dealing with containers, usually involves lots of heartache and effort to get working; however, ZAP is way ahead, and thankfully it just works.

On my host running Docker, it's a case of running this command and waiting for the image to get pulled down and run. When it's finished, you might get a slightly strange ioctl error (Figure 1), which is innocuous and your prompt (pun intended) to enter your TightVNC password.

Figure 1: The innocuous ioctl error password prompt; type your password when you see it.

Immediately afterward, you're asked to repeat the password and then just answer y to save the password inside the container. It's worth mentioning at this point that your container is going to be destroyed immediately after you stop it, unless you log in and run a script to get the GUI working with the -d (detach) option (Listing 1). If you're just testing the GUI to see if it is working correctly and your container will be short lived, then using a simple VNC password is fine to get you going.

Listing 1

Running a Persistent ZAP Container

root@chris:~# docker run -d -u zap -p 5900:5900 -p 81:8080 -i owasp/zap2docker-stable
03736c2a2088ef47dc4e2a82fbdf5f153e34f05834fecf23ede46c2061fda423
root@chris:~# docker exec -it 03736 bash
zap@03736c2a2088:/zap$ x11vnc --forever --usepw --create
Enter VNC password:
Verify password:
Write password to /home/zap//.vnc/passwd?  [y]/n y
Password written to: /home/zap//.vnc/passwd
[snip...]
The VNC desktop is:      03736c2a2088:0
PORT=5900

Assuming your firewalls and the planets are aligned correctly, it's a case of installing a package called xtightvncviewer and pointing it at the preset PORT in the output in Listing 1. I'm using Debian Mint, so I just run a command to install the simple viewer:

$ apt install xtightvncviewer

Now all you need to do is point xtightvncviewer at your server's IP address. You don't even have to add a colon and a port number in the terminal if you haven't changed the default port from 5900. (I recommend you change the default port for extended use to mitigate automated attacks on the well-known TCP 5900 port, which, believe me when I say, has some unwelcome history.) If you don't add an IP address, you'll see an old X Windows-style dialog box, but for ease, assuming you've stuck with TCP port 5900, simply type the following line in a new terminal, inserting your IP address instead of <1.2.3.4>:

$ xtightvncviewer <1.2.3.4>

If you'd like more Docker information, you'll find more options on the GitHub page [8].

The Gooey

Figure 2 shows the great reveal: ZAP's GUI served courtesy of a friendly neighborhood Docker over VNC. A generous level of detail, help, and options are available within the GUI. Notice the questions about persistence before you begin your session and see Listing 1 for Docker's part in making that possible.

Figure 2: A sight for sore eyes if you've been staring at terminals all day: the ZAP GUI in all its glory.

I will leave you to explore the application (carefully and targeting only your own systems) and return to the API, which can be integrated in true DevOps fashion within a CI context.

However, first, I would be remiss not to mention the Check for Updates option under the Help menu. If you want to see a list of the innards of the beast (and by that I mean which add-ons give ZAP its functionality), check for updates. Figure 3 shows what I see when asked which add-ons I want to update.

Figure 3: When checking for updates, you're shown a list of add-ons available immediately, along with the option to update them all.

Incidentally, if you mouse over the Description field of an add-on, you are offered a very helpful yellow pop-up box with details of the add-on, including a note related to its level of maturity.

Piping Hot

With the basics under your belt and fully appreciating that by harnessing the power of ZAP you can get some very useful scanning results (and enjoy the minimal setup time involved and not very steep learning curve), you now need to focus on how to access the ZAP API.

When dealing with automated execution from triggered, event-fired scans, you do not need to be overly concerned with persistence or the GUI. In some circumstances, you might just automate tasks using Docker commands and not by accessing the API directly. In the following simple example, I fire up a Docker container for a specific task, such as a baseline scan (a safe, passive scan) of a website:

$ docker run -t owasp/zap2docker-stable zap-baseline.py -t https://www.chrisbinnie-devsecops.com

The above command will, by default, run for one minute against the target with passive scanning and warn on all issues. All parameters are configurable, as you'd expect from such a sophisticated tool, including adding regex to keep certain URLs from being tested.

If you want to check what options are available, access the zap-baseline.py script by running it without options through Docker or by entering the container, as in Listing 1, and running the script. Here's the simple no-options route:

$ docker run -t owasp/zap2docker-stable zap-baseline.py

Running the command without options brings up a useful help page (Figure 4).

Figure 4: Some of the safe baseline script options that aren't destructive, just informative.

My favorite choice is to create my own config file with the -g switch, which generates a file that can be edited to switch certain tests off in future scans. The docs suggest the following set of command-line options to generate a config file and a report:

$ docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py -t https://www.chrisbinnie-devsecops.com -g generated_file.conf -r shiny_report.html

In Listing 2, you can see some partial results from a potentially automated baseline scan.

Listing 2

Baseline Scan Results

Total of 18 URLs
PASS: Cookie No HttpOnly Flag [10010]
PASS: Cookie Without Secure Flag [10011]
PASS: Password Autocomplete in Browser [10012]
PASS: Incomplete or No Cache-control and Pragma HTTP Header Set [10015]
PASS: Content-Type Header Missing [10019]
PASS: Information Disclosure - Debug Error Messages [10023]
PASS: Information Disclosure - Sensitive Informations in URL [10024]
PASS: Information Disclosure - Sensitive Information in HTTP Referrer Header [10025]
PASS: HTTP Parameter Override [10026]
PASS: Information Disclosure - Suspicious Comments [10027]
PASS: Viewstate Scanner [10032]
PASS: Secure Pages Include Mixed Content [10040]
PASS: Weak Authentication Method [10105]
PASS: Absence of Anti-CSRF Tokens [10202]
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]
FAIL-NEW: 0      FAIL-INPROG: 0 WARN-NEW: 4 WARN-INPROG: 0 INFO: 0 IGNORE: 0        PASS: 21

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=