I have got my Flask (Python) web application live and being deployed via CI/CD, and I have reports on my code coverage so that I know where code testing needs improving. However, this is not a moment to relax as up next is security testing.
Note: This blog post discusses security tooling which should not be run against any systems, software, sites or networks without consent from their owner.
Security Is Important
Security should be considered from early on in an applications design, as it is easier to build security in on day 1 and work with security features rather than trying to bolt security on at the last moment and finding those security features break parts of the app.
The Open Web Application Security Project (OWASP) provide feedback on web security, which I previously blogged about. I’ve attempted to implement controls / code in my project to improve security in the web application as I designed / built it.
Although I have considered security early on and tried to implement features to make my app secure, that does not mean I have not missed anything out. Thankfully OWASP has this covered thanks to OWASP ZAP.
Zed Application Proxy (ZAP) is a tool from OWASP which is used to scan web sites for security weaknesses. It can be installed locally or run from a Docker container. ZAP reports back what weaknesses have been found and this then gives an indication on what security improvements need to be carried out.
For this blog post I am going to run ZAP from my Kali Linux virtual machine and run my Flask web app from a Ubuntu Linux virtual machine. ZAP did not come with Kali but can be installed via a quick sudo apt install zaproxy command.
The initial start up screen of OWASP ZAP includes an “Automated Scan” option, which is very helpful as it carries out the security checking. Pressing the “Automated Scan” option leads to a screen where the URL or IP address of the target site is required.
As noted above, I’m running my application in a virtual machine, so I’m going to attack that virtual machine’s IP address. As the application is running on port 8000 I’ve appended the port details to the end of the IP address. If I wanted to scan my live application I could enter the URL here instead of an IP address –NOTE: Always get permission to conduct a scan/attack before carrying it out. If you are scanning a 3rd party hosting solution make sure to also check the terms and conditions before carrying out any scanning! With the address in place the scan can be started using the “Attack” button.
Depending on the size of the web site / web application being scanned this step may take some time. During this time ZAP is attempting HTTP GETs, POSTs etc and recording the responses. A progress bas is shown on screen (just below “Active Scan”) to help show progress, and the number of alerts (potential issues) can be found towards the bottom left of the window. These alerts are indicated by flags (red being the worst, blue being informational).
Once the scan is complete the number of alerts, and descriptions for the alerts are shown.
These alerts indicate security issues that should be worked on (either via code solutions or mitigated with another solution). Some of the alerts may be mitigated if another piece of software normally sits in front of the web app. For example, I’m running my web app in a virtual directly via Gunicorn, but in a production environment I would probably place Nginx in front of the app and that would handle some of the response headers.
Alert details can be expanded to show the URL they were found at, the risk level, the confidence level (i.e., low confidence may mean a false positive), the CWE ID, a description and a potential solution. Which is helpful when implementing the solution in code.
Although the OWASP ZAP software does a great job of scanning for and detailing alerts, there may times when you want to output / export the details to a more readable report. Thankfully the software can do this as well via the “Report” menu.