How To: Scripting OWASP Zap with JavaScript

OWASP Zap

OWASP Zap is a great open source security tool. I’m use it mainly on the CI/CD pipeline, to build dynamic security testing easily (checkout this post to find out how).

Today I want to talk about Zap scripting mechanism, and how it allows you to easily extend it. In case you’re not familiar with the scripting mechanism, checkout those slides. The slides are from a workshop that covers Zap’s scripting mechanism, by one of Zap’s authors, Simon Bennetts.

First Step: Writing the Script

Obviously, this is the first thing we’ll need to do. The rule I’m going to write is a rule that detects anonymous request — requests without Authorization header. Authentication is important and critical security mechanism, and that why I want Zap to detect all those requests and report them. Later, the developers can looks on those URLs and decide what to do.

Writing the rule is simple (And thanks to Kingthorin from Zap’s team who wrote it), here is the code:

The script is a passive scan rule, which means it can inspect the request and response, but not modify them. Let’s go quickly over the code to understand what it does:

  • Line 24 get the Authorization header from the request.
  • Line 27 check that the header is not present and that the returned status code is 200. If the status code is not 200, it means that the server has rejected the anonymous requests. An improvement should be to check that the status code is not 401 or 403, which is related to authentication issues. Anyway, for first iteration this is good enough.
  • Line 29 raise an alert to Zap. As any other rule, the alert should contains many details so the developers could understand what is the issue, why it is an issue and how it can be fixed.

Simple, right? The last challenges is writing tests for those rules, but this is something I’ll cover on another posts (when I actually have the time to work on testing :)).

Second Step: Loading the Script into Zap

The hard fact of using Docker

Loading the script using the GUI is relatively simple, and you can follow this guide to find out how. I want to use Zap in the CI/CD pipeline, so GUI is not an option. With a lot of help from Zap’s team, I was able to find out how this could be done (see this and this issues). The first thing we need to do is to modify Zap’s config file so it will load and enable our script:

Add this section to the end of config.xml (find the full file here). This section simply tell Zap’s to load our script and enable it. The next step is writing a custom Dockerfile that will load this file, and our script:

Let’s see what happens here:

  • Line 7 install and update a few addons
  • Line 9 copy the scripts folder with our scripts
  • Line 11 copy the config.xml file
  • Line 15 set permissions so Zap can read the configuration file
  • Line 19 launch Zap with all the required arguments, so users of this Docker images will not have to bother.

To make sure Zap’s actually load the script, you can use this URL:

http://localhost:1234/JSON/script/view/listScripts/?zapapiformat=JSON&formMethod=GET

If everything was done correctly, you should see the script you added. If you want to see a full working setup, check out this repo. The repo contains the Dockerfile we’re using at Soluto to run Zap on our CI. I did all the changes described on this post on a branch, so you can also checkout the pull request.

Conclusion

Now you know how you can easily extend Zap using your favourite language (which can be JavaScript, Ruby, Python etc). This gave you another easy way to customize Zap to your needs. Go ahead and give it a try, I’m looking forward to hear about your experience!

Like what you read? Give Omer Levi Hevroni a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.