DevSecOps Tutorial: How to implement DAST Zap Proxy in CI/CD Pipeline

DevSecOps Tutorial: How to implement DAST Zap Proxy in CI/CD Pipeline


I will brief the step by step how we can implement Dynamic Analysis Security Test (DAST) in your CI/CD pipeline. Before we can proceed with the nitty-gritty of of the CI/CD pipeline steps, below is the pre-requisite of this tutorial:


CI Tool: An account of SaaS GitLab/GitLab on-premises and GitLab Runner. Your GitLab Runner must be docker-executor enable, you may setup it via this link.

Project / Source Code: We will use free/open-source django project via

DAST Tool - ZAP Proxy

In this tutorial we will implement DAST tool called OWASP Zed Attack Proxy (ZAP) , it's a free and Open-Source web application vulnerability scanner which can find commonly found security like OWASP Top Ten. It devoted foreign volunteer crew, is one of the most common free-safety instruments in the world. This will also help you detect security vulnerabilities in your web apps as you create and check your software. This is also an excellent tool for seasoned pentesters to be used for manual safety checking.


ZAP Features

  • Swing based UI for desktop mode
  • Comprehensive REST API for daemon mode
  • Plug in architecture (add-ons)
  • Online ‘marketplace’ (all free:)
  • Release, beta and alpha quality add-ons
  • Traditional and ajax spiders
  • Passive and active scanning
  • Highly configurable, eg scan policies
  • Highly scriptable

ZAP Scans Type

There are 2 type of ZAP scans, they different by the following characteristics;


Step 0 : Setup a GitLab Account and GitLab Runner

If you don't have GitLab account yet, please refer this URL to setup it 1st, because below steps actually after you go setup your GitLab.

We will be use website as our destination which website is published by IBM Corporation for the sole purpose of demonstrating the effectiveness of IBM products in detecting web application vulnerabilities and website defects.

Step 1: Add zap-baseline Python file in GitLab repository

In order us to use zap-baseline scanner, we need to add new file in our GitLab repository and name it as you can directly use a docker image for zap-baseline scan from official OWASP page below. You can refer in OWASP's GitHub page here.

  • Python File

You can find file by click here.

  • Docker Image
###Pull Docker Image
docker pull owasp/zap2docker-stable

###To Use Zap-Baseline Scan
docker run -t owasp/zap2docker-weekly -t

Step 2: GitLab Repo setup & Clone django-nv source code

Once we clone the repo(as shared above and create new project in our GitLab), we need to update yml file below;


Step 3: Update your .gitlab-ci.yml file

 - build
 - test
 - integration
 - prod

  stage: build
    - echo "This is a build step"
    - echo "some tool output" > output.txt
    paths: [output.txt]

  stage: integration
   - docker run -t --rm owasp/zap2docker-stable -t
   # Clean up to save disk space
   - docker rmi owasp/zap2docker-stable 
  allow_failure: true

  stage: prod
    - echo "This is a deploy step"
  when: manual # Continuous Delivery

Step 4: Commit YML file and Run the CI/CD Pipeline

Once, we done editing our .gitlab-ci.yml file, we need to click "commit" button below to auto-deploy or run our SAST test in CI/CD pipeline


Step 5: Run CI/CD Pipeline and See DAST tools result JSON/XML file. We can see our CI/CD pipeline running in pipeline page;


Step 6: See Zap-Baseline Scanner Result

To see our Zap-Baseline scanner result, we can click on Test stage on zap-baseline job and see our zap-baseline scanner result as below;

$ docker run -t --rm owasp/zap2docker-stable -t
Status: Downloaded newer image for owasp/zap2docker-stable:latest
2020-08-04 02:55:13,370 Params: ['', '-daemon', '-port', '35342', '-host', '', '-config', 'api.disablekey=true', '-config', '*', '-config', 'api.addrs.addr.regex=true', '-config', 'spider.maxDuration=1', '-addonupdate', '-addoninstall', 'pscanrulesBeta']
Aug 04, 2020 2:55:16 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Total of 86 URLs
PASS: Cookie No HttpOnly Flag [10010]
PASS: Cookie Without Secure Flag [10011]
PASS: Content-Type Header Missing [10019]
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: Open Redirect [10028]
PASS: Cookie Poisoning [10029]
PASS: User Controllable Charset [10030]
PASS: User Controllable HTML Element Attribute (Potential XSS) [10031]
PASS: Viewstate Scanner [10032]
PASS: Directory Browsing [10033]
PASS: Heartbleed OpenSSL Vulnerability (Indicative) [10034]
PASS: Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) [10037]
PASS: X-Backend-Server Header Information Leak [10039]
PASS: HTTP to HTTPS Insecure Transition in Form Post [10041]
PASS: HTTPS to HTTP Insecure Transition in Form Post [10042]
PASS: User Controllable JavaScript Event (XSS) [10043]
PASS: Big Redirect Detected (Potential Sensitive Information Leak) [10044]
PASS: Retrieved from Cache [10050]
PASS: X-ChromeLogger-Data (XCOLD) Header Information Leak [10052]
PASS: CSP Scanner [10055]
PASS: X-Debug-Token Information Leak [10056]
PASS: Username Hash Found [10057]
PASS: X-AspNet-Version Response Header Scanner [10061]
PASS: PII Disclosure [10062]
PASS: Timestamp Disclosure [10096]
PASS: Hash Disclosure [10097]
PASS: Cross-Domain Misconfiguration [10098]
PASS: Weak Authentication Method [10105]
PASS: Reverse Tabnabbing [10108]
PASS: Modern Web Application [10109]
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: Incomplete or No Cache-control and Pragma HTTP Header Set [10015] x 65 (200 OK) (200 OK) (200 OK) (200 OK) (200 OK)
WARN-NEW: Cross-Domain JavaScript Source File Inclusion [10017] x 1 (200 OK)
WARN-NEW: X-Frame-Options Header Not Set [10020] x 63 (200 OK) (200 OK) (200 OK) (200 OK) (200 OK)
WARN-NEW: X-Content-Type-Options Header Missing [10021] x 101 (200 OK) (200 OK) (200 OK) (200 OK) (200 OK)
WARN-NEW: Strict-Transport-Security Header Not Set [10035] x 178 (200 OK) (404 Not Found) (404 Not Found) (200 OK) (200 OK)
WARN-NEW: Server Leaks Version Information via "Server" HTTP Response Header Field [10036] x 181 (200 OK) (404 Not Found) (404 Not Found) (200 OK) (200 OK)
WARN-NEW: Content Security Policy (CSP) Header Not Set [10038] x 140 (200 OK) (404 Not Found) (404 Not Found) (200 OK) (200 OK)
WARN-NEW: Secure Pages Include Mixed Content [10040] x 3 (200 OK) (200 OK) (200 OK)
WARN-NEW: Cookie Without SameSite Attribute [10054] x 2 (200 OK) (404 Not Found)
WARN-NEW: Absence of Anti-CSRF Tokens [10202] x 140 (200 OK) (404 Not Found) (404 Not Found) (200 OK) (200 OK)

As the output stated we have passed :41 scans and warning:10 info from the scanning.


We accomplished setup our DAST ZAP-Baseline scanning in CI/CD pipeline. So far we had done below;

  1. We had setup and clone django-nv source code in GitLab.
  2. We added new Python file for ZAP-Baseline in our GitLab repository.
  3. We updated .gitlab-ci.yml file with Docker Zap-Baseline DAST tool
  4. We successfully found the vulnerability in our code from SAST-Bandit jobs scanning.
  5. We have sast-bandit report JSON file as our vulnerability report for improve plan in our codes.

Next you should read

What Infrastructure as a Code (IaC) Role in DevSecOps pipeline.

Tutorial -> How to implement Ansible to Hardening Server in CI/CD Pipeline.

What is Compliance as a Code.

Share Tweet Send