The ZAP Client API is a project built on top of the ZAP Java API. It creates a layer of abstraction over all the calls to ZAP's API, simplifying the configuration and execution process for applications that want to use ZAP. Moreover, the ZAP Client API adds support for CAS authentication, not supported by default by ZAP or its API, as well as authentication via Selenium, which can be used on many other complex authentication strategies.
To use the API, just add the following dependency to your project:
<dependency>
<groupId>br.com.softplan.security.zap</groupId>
<artifactId>zap-client-api</artifactId>
<version>${zap-client-api.version}</version>
</dependency>Available versions can be found here.
The API's main class is ZapClient, which receives an instance of ZapInfo in its constructor and, optionally, an instance of AuthenticationInfo for analysis with authentication. ZapClient has only one public method: analyze(). This method starts a ZAP analysis and receives as parameter an instance of AnalysisInfo.
To use the API, one just needs to create those objects and call analyze(). The analysis output are the reports generated by ZAP, represented by an instance of the ZapReport class.
This class keeps all the necessary information regarding the ZAP instance that will be used. A builder is provided to make it easier to create objects of this class. It has three main methods:
buildToUseRunningZap()buildToRunZap()buildToRunZapWithDocker()
As it's clear by the methods' names, besides being possible to run an analysis with a running instance of ZAP, it's also possible to automatically start ZAP - via local installation or docker - to run the analysis. ZAP is also automatically finalized when the analysis ends.
Optionally, it's also possible to define the value of each parameter through the builder. Here are some examples:
// To use an instance of ZAP that is already executing, it's only necessary to inform ZAP's host and port
ZapInfo runningZapInfo = ZapInfo.builder().buildToUseRunningZap("localhost", 8080);
// To automatically start ZAP, the directory where ZAP is installed is required
ZapInfo runZapInfo = ZapInfo.builder().buildToRunZap(8080, "C:\\ZAP");
// To run ZAP via Docker, Docker must be locally installed and the application must have permission to run Docker
ZapInfo dockerZapInfo = ZapInfo.builder().buildToRunZapWithDocker(8080);
// The attributes can also be manually defined (dockerZapInfo is equivalent to newDockerZapInfo, for instance)
ZapInfo newDockerZapInfo = ZapInfo.builder().port(8080).shouldRunWithDocker(true).build();
// The 'path' attribute is enough to make sure ZAP will be automatically started
ZapInfo newRunZapInfo = ZapInfo.builder().port(8080).path("C:\\ZAP").build(); // equivalent to runZapInfo
// Lastly, both strategies can be used together
ZapInfo runningZapInfoWithTimeout = ZapInfo.builder().initializationTimeoutInMillis(30000L).buildToRunZap(8090, "C:\\ZAP");While ZapInfo stores everything related to ZAP, AuthenticationInfo keeps all the parameters needed for authentication. A builder is also provided to help create objects of this class. It has four main methods:
buildHttpAuthenticationInfo()buildFormAuthenticationInfo()buildCasAuthenticationInfo()buildSeleniumAuthenticationInfo()
These methods make it easier to create AuthenticationInfo instances for each authentication type supported so far: HTTP, form based, CAS and Selenium. Both methods receive as parameters the minimum necessary for each authentication type. However, it will normally be necessary to provide aditional parameters (to enable re-authentication, for instance). There are many options that can be set; the most common cases are presented below:
// On form based authentication, the required parameters are just loginUrl, username and password
AuthenticationInfo formInfo = AuthenticationInfo.builder()
.buildFormAuthenticationInfo("http://myapp/login", "username", "password");
// The same stands for Selenium authentication, although you could add some parameters like the web driver to be used
AuthenticationInfo seleniumInfo = AuthenticationInfo.builder()
.seleniumDriver("phantomjs").buildSeleniumAuthenticationInfo("http://myapp/login", "username", "password");
// For HTTP authentication, no loginUrl is needed, but the hostname and realm are required
AuthenticationInfo httpInfo = AuthenticationInfo.builder()
.buildHttpAuthenticationInfo("username", "password", "hostname", "realm");
// For CAS authentication, it's also necessary to inform a protected page for each context that will be analyzed
// This page will be automatically accessed after authentication and before ZAP's scan, avoiding redirections during the scan
AuthenticationInfo casInfo = AuthenticationInfo.builder()
.buildCasAuthenticationInfo("http://myapp/login", "username", "password", "http://mydomain/myapp/protected/somePage");
// To enable re-authentication (making sure the whole analysis will be authenticated), simply define a value for either loggedInRegex or loggedOutRegex
AuthenticationInfo formReauthInfo = AuthenticationInfo.builder()
.loggedInRegex("\\Q<a href=\"logout.jsp\">Logout</a>\\E")
.buildFormAuthenticationInfo("http://myapp/login", "username", "password");
// It's possible to define pages that won't be scanned (useful to exclude logout pages from the scan if re-authentication is not possible)
AuthenticationInfo formExcludeInfo = AuthenticationInfo.builder()
.excludeFromScan("http://myapp/logout")
.buildFormAuthenticationInfo("http://myapp/login", "username", "password");This class keeps information related to the analysis.
targetUrl: URL of the application that will be scanned;spiderStartingPointUrl: starting point URL for the Spider (and AJAX Spider, in case it runs);activeScanStartingPointUrl: starting point URL for the Active Scan;context: the context URLs to be set on ZAP (absolute or relative);analysisTimeoutInMinutes: analysis timeout;shouldStartNewSession: indicates whether a new session should be started on ZAP before the analysis;analysisType: analysis type. There are several types available.
These types are defined in the AnalysisType enum. WITH_SPIDER is the default type, which executes ZAP's Spider before the Active Scan. For applications that rely on AJAX, it might be interesting to execute the available AJAX Spider after the default Spider is executed. The type WITH_AJAX_SPIDER defines this strategy. ACTIVE_SCAN_ONLY executes only the Active Scan. This is useful when the application navigation was done through a proxy with ZAP (via Selenium tests, for instance) and there is no need to run the Spider. Lastly, there are two options intended to run only the passive scan: SPIDER_ONLY and SPIDER_AND_AJAX_SPIDER_ONLY.
The AnalysisInfo instance is passed to ZapClient's analyze() method. Therefore, it's possible to execute different analysis from the same ZapClient instance.
The analyze() method returns a ZapReport instance that holds the reports generated by ZAP. Besides those, a new report is also generated with all the URLs visited by the Spider. This new report is important because it can be used to show if the Spider did, in fact, navigate through the application. Depending on these results, it might be possible to conclude if the authentication actually worked.
Running an analysis on an executing instance of ZAP:
ZapInfo zapInfo = ZapInfo.builder().buildToUseRunningZap("localhost", 8080);
ZapClient zapClient = new ZapClient(zapInfo);
ZapReport zapReport = zapClient.analyze(new AnalysisInfo("http://localhost:8090/bodgeit", 120));
System.out.println(zapReport.getHtmlReportAsString());
System.out.println(zapReport.getHtmlSpiderResultsAsString());Running an analysis with automatic ZAP initialization and form authentication:
ZapInfo zapInfo = ZapInfo.builder().buildToRunZap(8080, "C:\\ZAP");
AuthenticationInfo authenticationInfo = AuthenticationInfo.builder()
.loggedInRegex("\\Q<a href=\"logout.jsp\">Logout</a>\\E")
.buildFormAuthenticationInfo("http://localhost:8090/bodgeit/login.jsp", "user", "pass");
ZapClient zapClient = new ZapClient(zapInfo, authenticationInfo);
ZapReport zapReport = zapClient.analyze(new AnalysisInfo("http://localhost:8090/bodgeit", 120));
System.out.println(zapReport.getHtmlReportAsString());
System.out.println(zapReport.getHtmlSpiderResultsAsString());⚡