Automated Functional Tests, a healthy food for Automated Security Tests — Part 2

Nishant Shah
9 min readJun 27, 2020

--

Selenium Integrated With Zed Attack Proxy For Automated Security Testing

This article is in continuation of the PART 1 where we have come up with the approach of automating the security testing using a functional UI Automation tool and security testing tool. If you have not already gone through it then request you to first refer it before moving ahead.

Here, we will create a POC using selenium and a security testing tool called Zed Attack Proxy(ZAP). I am assuming that you all know how to do the Functional UI Automation task using selenium (with java or any tech) OR any other UI Automation Tool. So, I will mainly be concentrating on the part which is specific to ZAP setup and integration.

In order to create a POC, one of the really important stuff we will require is AUT (Application Under Test). Remember that you cannot or rather should not be performing security scans on LIVE web applications or even applications running on your staging environments. The simple reason being security tools are meant to bombard your app with a huge number of malicious requests. Hence it is capable of bringing your systems down. It’s highly recommended to have an isolated environment setup exclusively to perform Security Scanning/Testing.
So, for this POC, we will first set up a sample test web application on our local machine. This application has been intentionally created to have security vulnerabilities.

Having AUT up and running

There is a VM called Metasploitable (an intentionally vulnerable Linux Virtual Machine) created by the Security Testing Community, which can be used by Ethical Hackers and Pentesters to learn and perform security testing. This VM also has a vulnerable web application called ‘Mutilidae’. Setting up this VM on Windows as well as Mac machine is quite easy and straightforward. Please refer to this link to know the details of setting it up.
Note :- You will require to have VirtualBox installed on your machine before you go ahead with setting this up.
Once you set it up as mentioned in the above link, you should be able to access the mutilidae app by opening following url on your local machine :-
http://<ip address of vm>/mutillidae/
In case you get any database errors while registering a new user in this web application, then you fix it by referring to this.

Having Selenium Script Up And Running

Once you have your AUT up and running, we can now proceed ahead with the next step. Now, we will automate a basic scenario of this web app using Selenium + Java. Following is the scenario of the app we will automate :-

  1. Open the mutillidae app home page
  2. Login to the app using any already registered user.
  3. Navigate to OWASP Top 10 -> A2 — Cross Site Scripting (XSS) -> Persistent (Second Order) -> Add to your blog.

4. Add some text to the blog.

Execute this script on any browser of your choice and make sure it’s working fine.

I won’t go into the details of how to setup selenium webdriver and write selenium scripts as most of the QA Engineers are familiar with selenium or any other UI Automation tool. Also, in case you are not aware then there are ample of online tutorials available to get started.
However, one important thing we will require is to be able to run the selenium script proxying to a specific port (where our ZAP tool will be listening). There is a provision in selenium webdriver itself to achieve this. i.e. While initializing your webdriver you need to have following lines of code (the below code is for java) :-

Proxy proxy = new Proxy();
proxy.setHttpProxy("localhost:" + prop.getProperty("zapPort"));
proxy.setSslProxy("localhost:" + prop.getProperty("zapPort"));
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("proxy",proxy);
capabilities.setBrowserName("chrome");

This will enable the selenium automation execution to happen via the proxy port specified above.

Zed Attack Proxy(ZAP) Integration Into Selenium Project

Now comes the most interesting step, which you must be waiting for :- “ZAP Integration”.
Before, we proceed ahead with the integration part, first let’s just cover the ZAP installation.
Download and Install ZAP from this link.
Open the ZAP app. While launching it may prompt you “Whether you want to persist the session”. Keep the default selection as is, it should be “No, I don’t want to persist the session…..” and click on Start.

ZAP — Persistent Session Prompt

Now, it may ask you for installing some add-ons. Just dismiss that popup if asked for.
The ZAP should now be up and running.

To check at which port the ZAP is listening at, navigate to following menu options from the top menu bar :- Tools -> Options. In the options popup, select the Local Proxies option from the left pane:-

ZAP — Local Proxies Screen

By default it runs on port 8080. But, in case 8080 port is already consumed by some other process then you might have to set a different port here and then click on OK button. This will make the ZAP listen on that particular port. E.g. here we are using the port number 8888.

In case you want to see how ZAP UI shows the captured request and things around it, then you can set the proxy from your browser to 8888 (can leverage a chrome extension named foxyproxy for the same. Also available in firefox).
After setting the proxy, try performing the same scenario in mutillidae web application, i.e. the scenario automated above.
After performing the actions on the web app, you must see some requests been captured in the ZAP app.

ZAP — Requests Captured

The above exercise is just to give you a look and feel about ZAP and how the requests get proxied by ZAP and shown on the UI.
If you want you can explore more areas of ZAP from it’s UI like performing Active Scanning and others.
We won’t go into much details about the ZAP UI as our interest is in automation and for automation we want ZAP to be running in headless mode.

However, before you close your ZAP UI, one thing you will require is an API key. We will see later why we need this API key. But, for now, just open the following screen in ZAP UI to fetch it :-
Tools -> Options -> API

ZAP — API key

Now, simply close down the ZAP UI.

ZAP can be easily run in headless mode via some commands. For mac you can simply create a .sh file named StartZap.sh with following commands :-

#!/bin/bash
cd /Applications/OWASP\ ZAP.app/Contents/Java
./zap.sh -daemon -port 8888 -config api.key=XXXXXXXXXXX

Note :- api.key value should be the same API Key which you copied in the above step. You should have your ZAP in the Applications for this to work.
Also make this .sh file executable.
For windows, you can similarly create a .bat file.

Now, open your selenium Java project.
Here, in the whole article I will be giving an example of Selenium + Java + TestNG. But, this is technology agnostic and you can figure out your respective technology equivalent stuff. The logic will remain the same.

Create a folder named Lib in the root project directory and place the above StartZap.sh file in it.
Idea here is to write down the logic to call and execute the StartZap.sh file before our selenium code runs as we want ZAP to be up and running and listening to the 8888 port before our selenium execution starts. So, simply place this logic in your @BeforeClass or @BeforeSuite whatever holds true for your project.
Here is a java code to run this .sh file :-

ProcessBuilder pb = new ProcessBuilder(“sh”, “StartZap.sh”, “&”);
pb.directory(new File(“Lib”));
Process p = pb.start();

So, until now what have we achieved via automation??

A selenium java project, which :-
1. Starts ZAP in headless mode listening at port 8888
2. Executes our selenium test by proxying to port 8888.

This is cool !! We are slowly reaching our goal.

By the time our selenium test finishes execution, ZAP would have captured all the requests made by our test scenario and would have also performed a Passive Security Scan on those requests.
We had seen in the previous chapter that Passive Security scan just scans all the requests received by ZAP and tells you if there are any security loopholes in those requests. So, with passive scan we can know a very high level security issues.

However, our goal is to perform Active scan as well and know more detailed security vulnerabilities like SQL and XSS Injections and many more.
Let’s see how this can be automated.

In Java, there is a ZAP library called zap-clientapi available which can help us in achieving this. Below is the maven tag to fetch the library and its dependencies:-

<dependency>
<groupId>org.zaproxy</groupId>
<artifactId>zap-clientapi</artifactId>
<version>1.8.0</version>
</dependency>

In your java class, this is how you can initialize the Zap’s ClientApi object :-

ClientApi clientApi = new ClientApi(“localhost”, zapPort, apiKey);

Now, you can use the huge chunk of methods available for different ZAP functionalities via this clientApi object.

Firstly, what we will do is immediately after the logic where we have executed the StartZap.sh file, need to do something like this :-

int waitForZapToStart = 0;
while(true) {
try {
((ApiResponseElement) clientApi.core.version()).getValue();
break;
} catch (ClientApiException ex) {
if(waitForZapToStart==15)
throw new Exception("Unable to start zap");
Thread.sleep(2000);
waitForZapToStart+=1;
}
}

Since ZAP does not immediately start running after executing it, the above logic will give a breather time for ZAP to start.
((ApiResponseElement) clientApi.core.version()).getValue();
This statement above fetches the version of ZAP. This will succeed only when ZAP is up and running, otherwise it will keep on throwing exception.

Next part is performing the Active Scan. We need to perform active scan only after the selenium test(s) has been completed. So, either in the @AfterClass or @AfterSuite depending upon your structure we can write the below code for performing active scanning :-

public void performActiveScan() throws ClientApiException, InterruptedException {
System.out.println("*** Starting the active scan ***");
ApiResponse resp = clientApi.ascan.scan(target,"True","False",null,null,null);
String scanId;
int progress;

scanId = ((ApiResponseElement) resp).getValue();

while(true){
Thread.sleep(5000);
progress = getScanStatus(scanId);
System.out.println("Active scan percentage is :- " + progress + "%");
if(progress >= 100)
break;
}
System.out.println("*** Active scan finished!! ***");
}

There are two things happening in the above section of code. We have first started the active scan on the target url (root url). Then, we are continuously measuring the status of the scan. As soon as it reaches 100% we are breaking the loop, so that next actions can be carried out.

Once active scan is done, we need an HTML report of all the issues identified in active and passive scans. We get a consolidated report of the scans. Below is the code which does it :-

public void generateHtmlReport() throws ClientApiException, IOException {
byte[] reportInBytes = clientApi.core.htmlreport();
File file = new File("Reports/zap_scan.html");
FileOutputStream fos = new FileOutputStream(file);
fos.write(reportInBytes);
fos.close();
}

This generates an HTML Report of the Security Scan(s) in the
Reports->zap_scan.html file in the root directory of the project. Below is how the report looks :-

ZAP — HTML Report Of Scanning

It gives proper details of each and every security vulnerability found in the scan.

Finally, after the report generation logic, just put down the logic to shut down the ZAP. This is how it can be done via the clientApi :-

clientApi.core.shutdown();

WOAAHHHH!! It’s done

We have managed to perform an automated Security Testing with the help of our Functional UI Automation Tests and ZAP.

In these days of massive competition, it’s really important that your application remains properly secured and does not have any loose ends which can be exploited by the hackers. Also, recently we are seeing a massive increase in the incidents of hacking, mainly to dampen the company’s reputation in the market.
Hence, it’s high time that QA’s start taking security seriously and use these kinds of automation techniques to have security testing done with the help of Functional Tests.

If there is no dedicated security team in your company/project then try to put some extra efforts and achieve this automation. This process will definitely help to discover some obvious and basic security vulnerabilities in your web application well before it reaches production.

If you already have a security team then also this automation will massively help your pen testers. With this automation in place, they would be able to concentrate on more innovative and in depth security tests. This will indeed make your app more secured.

Happy Security Testing Folks !! :)

--

--

Nishant Shah

QA Engineer by profession and love finding out ways to automate tedious and repetitive activities