View on GitHub

Grails ZAP Security Tests Plugin

Automated security tests using the OWASP Zed Attach Proxy

Download this project as a .zip file Download this project as a tar.gz file

Introduction

The ZAP Security Tests plugin for Grails allows you to run completely automated security tests using the OWASP's Zed Attack Proxy (aka ZAP) to scan your web application for detecting security vulnerabilities.

ZAP is an easy to use integrated penetration testing tool ideal for developers and functional testers that provides automated scanners as well as a set of tools that allow you to find security vulnerabilities manually. You can find more details about the ZAP features at the project website.

How It Works?

The ZAP Security Tests plugin extends the Grails default functional tests behaviour adding a new -zap option that you can pass to convert your functional test suite into security tests.

If you specify the -zap option the plugin controls ZAP programmatically through its REST based API in order your browser-based functional tests run normally, but using ZAP as an HTTP intermediary proxy. This way ZAP can learn the application URLs visited by functional tests. If functional tests pass successfully then the plugin requests ZAP to actively scan the application by using known attack vectors against the application URLs. If any vulnerability is detected then the test execution will fail and report the corresponding security warnings.

The plugin executes the following steps:

  1. Starts ZAP (in GUI or daemon mode, after the plugin's configuration).
  2. Waits for ZAP to be started and listening at the configured port.
  3. Establishes system properties to pass proxy's host and port values so your functional tests can be configured to use the specified proxy.
  4. Executes your functional tests.
  5. Instructs ZAP to spider through the site to discover more application resources.
  6. Requests ZAP to launch an active scanning on all the collected URLs.
  7. Stores the resulting ZAP session under the test reports directory, so you can inspect security results later.
  8. Checks for security alerts. If any vulnerability has been detected the execution fails outputting the corresponding security alerts.
  9. Stops ZAP proxy.

As you may be thinking, this plugin is useful to integrate security testing in your continuous integration process.

The idea for this plugin was inspired by the Security Testing in Development and QA presentation by Simon Bennetts of the Mozilla Security Team.

Installation

Add the following dependency to your plugins block at BuildConfig.groovy:

compile ":zap-security-tests:0.1.2"

Note that the plugin does not include the own ZAP proxy that should be previously installed in your box. You can download ZAP proxy from the downloads page.

Usage

Run security tests and generates reports

Usage:
grails [environment]* test-app [names]* -zap [-daemon]
Examples:
grails test-app -zap
grails test-app functional: -zap

Or you can run as security tests only certain functional test types:


grails test-app functional:spock -zap

If you want to run the proxy in daemon mode (e.g. in a headless server) you can specify the option -daemon:

grails test-app functional: -zap -daemon

Start or stop ZAP proxy

Usage:
grails start-zap [-daemon]
grails stop-zap

Sample application

If you want to see the plugin in action take a look at the sample application using the plugin with Geb-based functional tests.

Configuration

You can configure the plugin through the file ZapSecurityTestsConfig.groovy at the grails-app/conf directory.

Once installed, the plugin creates the following sample configuration file that you should edit to adapt to your environment:

import org.zaproxy.clientapi.core.Alert

zap {
    // Absolute path where ZAP is installed
    installDir = '/opt/zaproxy'

    // Address the proxy will bind
    proxyHost = 'localhost'

    // Port the proxy will listen
    proxyPort = 8090

    // System properties the plugin will set with proxy host and port values
    // to allow you to configure the functional tests to use the ZAP proxy
    proxyHostSystemProperty = 'ZAP_PROXY_HOST'
    proxyPortSystemProperty = 'ZAP_PROXY_PORT'

    // Subdirectory of test reports dir where ZAP sessions will be stored
    reportsDir = 'zap'

    // ignoredAlerts specify a collection of alerts (instances of
    // org.zaproxy.clientapi.core.Alert) that will be ignored if reported
    // by ZAP.
    //
    // Missing elements match everything, so the following collection of
    // ignoredAlerts will ignore all alerts of risk Low or Informational:
    //
    //   ignoredAlerts = [
    //       new Alert(null, null, Alert.Risk.Low, null),
    //       new Alert(null, null, Alert.Risk.Informational, null)
    //   ]
    //
    // Another example to ignore three specific security alerts:
    //
    //   ignoredAlerts = [
    //       new Alert('X-Content-Type-Options header missing', null),
    //       new Alert('X-Frame-Options header not set', null),
    //       new Alert('Content-type header missing', null)
    //   ]
    ignoredAlerts = []

    // requiredAlerts specify a collection of alerts (instances of
    // org.zaproxy.clientapi.core.Alert) that will fail if not present.
    requiredAlerts = []

    // Timeout in millisecond the proxy will wait for ZAP to start
    timeout = 10000

    // Enable debug in the REST based API interactions with ZAP
    debug = false
}

It's important to note that you should configure your functional tests to use the ZAP proxy when the system properties specified by the plugin are present. For instance, you can configure Geb-based functional tests through GebConfig.groovy in the following way:


driver = {
    def driver = new HtmlUnitDriver()
    if (System.getProperty('ZAP_PROXY_HOST') && System.getProperty('ZAP_PROXY_PORT')) {
        String zapProxyHost = System.getProperty('ZAP_PROXY_HOST')
        int zapProxyPort = System.getProperty('ZAP_PROXY_PORT').toInteger()
        driver.setProxy(zapProxyHost, zapProxyPort)
    }
    driver
}

Warning

It should be noted this plugin can only find certain types of vulnerabilities. Logical vulnerabilities, such as broken access control, will not be found by any active or automated vulnerability scanning, so manual penetration testing should always be performed in addition to active scanning to find all types of vulnerabilities in your applications.

Authors and Contributors

Plugin authored by The Rat Pack group of programmers.

Support

Having trouble with the plugin? Please send us your feedbacks or issues.