How to integrate application security testing in the CI/CD pipeline

ZAP.png

In this blog I’m going to build on my previous posts on agile security, DevSecOps culture and managing vulnerabilities in open source libraries to talk about automating application security testing.

The Open Web Application Security Project (OWASP) regularly publishes their top 10 web application security risks, covering example attack scenarios and mitigation strategies. Injection flaws, cross-site scripting and broken authentication never fail to make the list.

Security teams traditionally addressed these vulnerabilities through regular, often manual, application security testing. They then analyse these scan reports and communicated the issues to the engineers requesting a fix. Although this method still has its use, agile software development and associated drive to deliver working software quickly might introduce tension between security and development teams. Manual scans take time and critical vulnerabilities can stay unpatched in production systems for weeks if not months waiting to be prioritised.

A strong DevSecOps culture can bring these teams closer together but traditional approaches to application security testing have to be adapted to fit in. Drawn-out monthly security scans with a multitude of false positives will only irritate your developers, while cutting corners doesn’t fair well with security specialists.

Conducting security tests in the CI/CD pipeline removes the special standing of vulnerability scanning and brings it closer to the familiar unit and integration tests, bridging the gap between development and security. The aim is to detect security issues in the pipeline rather than checking for them in production later.

The OWASP Zed Attack Proxy (ZAP) has a handy baseline scan feature that can help address this challenge. The tool is open source and is also available as a Docker container. It has other advanced functionality, including fuzzing and beyond but here we will focus on the baseline scan for basic security controls only. The main reason for this is speed. Developers need quick feedback and the baseline scan can usually run in less than a minute. It’s also non-intrusive so shouldn’t disrupt the workflow too much.

When integrating ZAP in the CI/CD workflow, the CI platform will retrieve the ZAP Docker container to run it agains the application container. The CI platform will then either approve or reject the change depending on the output of the scan.

So when you run the following command (with your own URL):

docker run owasp/zap2docker-weekly zap-baseline.py -t https://myexampleapp.com

you would expect to see an output like this:

Total of 3 URLs
PASS: Cookie No HttpOnly Flag [10010]
PASS: Cookie Without Secure Flag [10011]
PASS: Incomplete or No Cache-control and Pragma HTTP Header Set [10015]
PASS: Cross-Domain JavaScript Source File Inclusion [10017]
PASS: Content-Type Header Missing [10019]
PASS: X-Frame-Options Header Scanner [10020]
PASS: X-Content-Type-Options Header Missing [10021]
PASS: Information Disclosure - Debug Error Messages [10023]
PASS: Information Disclosure - Sensitive Information in URL [10024]
PASS: Information Disclosure - Sensitive Information in HTTP Referrer Header [10025]
PASS: HTTP Parameter Override [10026]
PASS: Information Disclosure - Suspicious Comments [10027]
PASS: Viewstate Scanner [10032]
PASS: Secure Pages Include Mixed Content [10040]
PASS: Cookie Without SameSite Attribute [10054]
PASS: X-Debug-Token Information Leak [10056]
PASS: Username Hash Found [10057]
PASS: X-AspNet-Version Response Header Scanner [10061]
PASS: Timestamp Disclosure [10096]
PASS: Cross-Domain Misconfiguration [10098]
PASS: Weak Authentication Method [10105]
PASS: Absence of Anti-CSRF Tokens [10202]
PASS: Private IP Disclosure [2]
PASS: Session ID in URL Rewrite [3]
PASS: Script Passive Scan Rules [50001]
PASS: Insecure JSF ViewState [90001]
PASS: Charset Mismatch [90011]
PASS: Application Error Disclosure [90022]
PASS: Loosely Scoped Cookie [90033]
WARN-NEW: Web Browser XSS Protection Not Enabled [10016] x 2
https://myexampleapp.com/robots.txt
https://myexampleapp.com/sitemap.xml
WARN-NEW: Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) [10037] x 2
https://myexampleapp.com/robots.txt
https://myexampleapp.com/sitemap.xml
WARN-NEW: CSP Scanner: Wildcard Directive [10055] x 2
https://myexampleapp.com/robots.txt
https://myexampleapp.com/sitemap.xml
FAIL-NEW: 0 FAIL-INPROG: 0 WARN-NEW: 3 WARN-INPROG: 0 INFO: 0 IGNORE: 0 PASS: 29

Security alerts appear as warning by default and you can change pass and fail conditions in the config file. ZAP’s baseline scan is highly configurable and I encourage to check out its GitHub page for more details.

Advertisement

5 Comments

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s