DEV Community

Cover image for Securing Your Web Applications (DAST): A Deep Dive into OWASP ZAP Scans with Docker
Hassan Aftab
Hassan Aftab

Posted on • Edited on

Securing Your Web Applications (DAST): A Deep Dive into OWASP ZAP Scans with Docker

Scanning Localhost Application with Docker ZAP

Table of Contents

Introduction

Dynamic Application Security Testing (DAST) is a type of security testing that involves testing an application in its running state. Unlike static analysis, which examines the source code, DAST scans an application from the outside in, simulating an attacker’s perspective. This approach helps identify vulnerabilities that might be exploited in a real-world attack scenario, such as SQL injection, cross-site scripting (XSS), and other web application vulnerabilities.

One of the most popular tools for performing DAST is the Zed Attack Proxy (ZAP), an open-source security scanner maintained by the Open Web Application Security Project (OWASP). ZAP is designed to be easy to use, even for those new to application security, while also providing powerful features for advanced users.

Key Features of ZAP

  • Automated Scanning: ZAP can automatically scan web applications for security vulnerabilities.
  • Passive Scanning: Monitors HTTP traffic and passively scans for vulnerabilities without altering the request-response cycle.
  • Active Scanning: Actively probes the web application for vulnerabilities by sending various types of malicious requests.
  • Spidering: Crawls the web application to discover all the pages and endpoints that need to be tested.
  • API Integration: Provides a robust API that allows for integration with CI/CD pipelines for continuous security testing.
  • Extensibility: Supports various add-ons and plugins to extend its functionality.

Benefits of Using ZAP for DAST

  1. Comprehensive Coverage: ZAP can identify a wide range of vulnerabilities, including those listed in the OWASP Top Ten.
  2. Ease of Use: Its intuitive interface and extensive documentation make it accessible for beginners.
  3. Community Support: Being an OWASP project, ZAP benefits from a large community of contributors and users who help in improving and updating the tool.
  4. Cost-Effective: As an open-source tool, ZAP is free to use, making it an attractive option for organizations of all sizes.

Getting Started with ZAP

To start using ZAP for DAST scanning, follow these steps:

  1. Download and Install ZAP: ZAP is available for Windows, macOS, and Linux. You can download it from the official ZAP website.
  2. Configure Your Browser: Set up your web browser to use ZAP as a proxy to capture and inspect the HTTP traffic.
  3. Start Scanning: Use ZAP's spidering and scanning features to discover and test the web application's endpoints for vulnerabilities.
  4. Review and Mitigate: Analyze the scan results to identify vulnerabilities and take appropriate actions to mitigate them.

Setting up TIWAP

Step-by-Step Instructions to Set Up the Web Application

  • Clone the GitHub Repository

First, clone the repository to your local machine. Open your terminal and run the following command:

   git clone https://github.com/hassanaftab93/TIWAP.git 
Enter fullscreen mode Exit fullscreen mode

This command downloads all the project files from the GitHub repository to a directory named TIWAP on your local machine.

  • Navigate to the Project Directory

After cloning the repository, navigate into the project directory:

   cd TIWAP
Enter fullscreen mode Exit fullscreen mode

This changes your current directory to the TIWAP directory, where the project files are located.

  • Run Docker Compose to Spin Up the Web Application

Use Docker Compose to build and start the web application. Make sure Docker is installed and running on your system. Then run:

   docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Docker Compose Output

This command uses the docker-compose.yml file to build the Docker containers and start the application in detached mode (running in the background).

  • Verify the Application is Running

After running the Docker Compose command, verify that the application is running. Open your web browser and navigate to:

   https://localhost:8080
Enter fullscreen mode Exit fullscreen mode

browser webpage

or you can

   curl -k https://localhost:8080
Enter fullscreen mode Exit fullscreen mode

curl localhost

As seen in the images above, the web application up and running.

Docker Installation Instructions

In order for you to run any of these commands, you'll need to have Docker installed. You can view the instructions here: Get Docker: Installation Instructions.

Execution Instructions

Step 1: Pull the ZAP Docker Image

First, ensure you have Docker installed and running on your system. Then, pull the latest OWASP ZAP Docker image:

docker pull zaproxy/zap-stable:latest
Enter fullscreen mode Exit fullscreen mode

Before we start with the zap scans, lets first take a look at the docker image itself

Lets run the following command:

   docker run --rm -it zaproxy/zap-stable:latest bash
Enter fullscreen mode Exit fullscreen mode

This will take us inside the running container of the image and show us the contents in its default working dir, which is /zap

zap@6026a83c9b31:/zap$ ls -la
total 5632
drwxr-xr-x 1 zap  zap     4096 Oct  7 16:47 .
drwxr-xr-x 1 root root    4096 Oct 15 15:26 ..
-rw-r--r-- 1 zap  zap    10324 Oct  7 16:45 CHANGELOG.md
-rw-r--r-- 1 zap  zap     2167 Jan  2  1970 README
-rw-r--r-- 1 zap  zap       18 Oct  7 16:47 container
drwxr-xr-x 2 zap  zap     4096 Jan  2  1970 db
drwxr-xr-x 2 zap  zap     4096 Jan  2  1970 lang
drwxr-xr-x 2 zap  zap     4096 Jan  2  1970 lib
drwxr-xr-x 2 zap  zap     4096 Jan  2  1970 license
drwxr-xr-x 2 zap  zap     4096 Oct  7 16:47 plugin
drwxr-xr-x 3 zap  zap     4096 Jan  2  1970 scripts
drwxr-xr-x 1 zap  zap     4096 Oct  7 16:45 webswing
drwxr-xr-x 2 zap  zap     4096 Jan  2  1970 xml
-rw-r--r-- 1 zap  zap  5450049 Jan  2  1970 zap-2.15.0.jar
-rwxr-xr-x 1 zap  zap    26496 Oct  7 16:45 zap-api-scan.py
-rwxr-xr-x 1 zap  zap    24732 Oct  7 16:45 zap-baseline.py
-rwxr-xr-x 1 zap  zap    20576 Oct  7 16:45 zap-full-scan.py
-rwxr-xr-x 1 zap  zap     2977 Oct  7 16:45 zap-webswing.sh
-rwxr-xr-x 1 zap  zap      319 Oct  7 16:45 zap-x.sh
-rw-r--r-- 1 zap  zap      188 Jan  2  1970 zap.bat
-rw-r--r-- 1 zap  zap   123778 Jan  2  1970 zap.ico
-rwxr-xr-x 1 zap  zap     4231 Jan  2  1970 zap.sh
-rw-r--r-- 1 zap  zap    23306 Oct  7 16:45 zap_common.py

Enter fullscreen mode Exit fullscreen mode

As seen above in the output, we have 3 main python executable files that we can use for scans, later in the article we will see the flag to pass the python file name to use

  • zap-api-scan.py
  • zap-baseline.py
  • zap-full-scan.py

Step 2: Start Your Localhost Application

Make sure your local application is running on localhost. For example, if it's a web application, it might be accessible at
http://localhost:8080.

Step 3: Run the ZAP Scan

Use the following command to run the ZAP scanner against your localhost application. This command assumes your application is accessible on port 8080. Adjust the port number accordingly if your application uses a different port.

  • Linux/Unix

    docker run -v $(pwd):/zap/wrk/:rw --network="host" zaproxy/zap-stable zap-baseline.py -t https://localhost:8080 -r scan-report.html
    
  • Windows Powershell

    docker run -v ${PWD}:/zap/wrk/:rw --network="host" zaproxy/zap-stable zap-baseline.py -t https://localhost:8080 -r scan-report.html
    

Explanation of the Command

  • -v $(pwd):/zap/wrk/:rw

This option mounts the current directory ($(pwd)) to the /zap/wrk/ directory inside the container. The report will be saved in this directory.

  • --network="host"

This tells Docker to use the host's network, allowing the Docker container to access localhost.

  • zap-full-scan.py

This is a script provided by ZAP for running a full scan, which performs a deeper and more thorough scan. It will take a while though.

  • -t http://localhost:8000

Specifies the target URL for the scan. NOTE: You can however provide URL for your own web app as well, be it on localhost or hosted somewhere, hopefully not in production yet :D

  • -r scan-report.html

Specifies the name of the report file to generate.

Additional Flags to pass to Image

Usage: zap-baseline.py -t <target> [options]
    -t target         target URL including the protocol, eg https://www.example.com
Options:
    -h                print this help message
    -c config_file    config file to use to INFO, IGNORE or FAIL warnings
    -u config_url     URL of config file to use to INFO, IGNORE or FAIL warnings
    -g gen_file       generate default config file (all rules set to WARN)
    -m mins           the number of minutes to spider for (default 1)
    -r report_html    file to write the full ZAP HTML report
    -w report_md      file to write the full ZAP Wiki (Markdown) report
    -x report_xml     file to write the full ZAP XML report
    -J report_json    file to write the full ZAP JSON document
    -a                include the alpha passive scan rules as well
    -d                show debug messages
    -P                specify listen port
    -D secs           delay in seconds to wait for passive scanning 
    -i                default rules not in the config file to INFO
    -I                do not return failure on warning
    -j                use the Ajax spider in addition to the traditional one
    -l level          minimum level to show: PASS, IGNORE, INFO, WARN or FAIL, use with -s to hide example URLs
    -n context_file   context file which will be loaded prior to spidering the target
    -p progress_file  progress file which specifies issues that are being addressed
    -s                short output format - dont show PASSes or example URLs
    -T mins           max time in minutes to wait for ZAP to start and the passive scan to run
    -U user           username to use for authenticated scans - must be defined in the given context file (post 2.9.0)
    -z zap_options    ZAP command line options e.g. -z "-config aaa=bbb -config ccc=ddd"
    --hook            path to python file that define your custom hooks
    --auto            use the automation framework if supported for the given parameters (this will become the default soon)
    --autooff         do not use the automation framework even if supported for the given parameters
Enter fullscreen mode Exit fullscreen mode

Command Output


> docker run -v $(pwd):/zap/wrk/:rw --network="host" zaproxy/zap-stable zap-baseline.py -t https://localhost:8080 -r scan-report.html
Using the Automation Framework
Total of 19 URLs
PASS: Vulnerable JS Library (Powered by Retire.js) [10003]
PASS: In Page Banner Information Leak [10009]
PASS: Cookie No HttpOnly Flag [10010]
PASS: Cookie Without Secure Flag [10011]
PASS: Cross-Domain JavaScript Source File Inclusion [10017]
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: Open Redirect [10028]
PASS: Cookie Poisoning [10029]
PASS: User Controllable Charset [10030]
PASS: User Controllable HTML Element Attribute (Potential XSS) [10031]
PASS: Viewstate [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: Secure Pages Include Mixed Content [10040]
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: Cookie without SameSite Attribute [10054]
PASS: CSP [10055]
PASS: X-Debug-Token Information Leak [10056]
PASS: Username Hash Found [10057]
PASS: X-AspNet-Version Response Header [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: Dangerous JS Functions [10110]
PASS: Session Management Response Identified [10112]
PASS: Verification Request Identified [10113]
PASS: Script Served From Malicious Domain (polyfill) [10115]
PASS: Private IP Disclosure [2]
PASS: Session ID in URL Rewrite [3]
PASS: Script Passive Scan Rules [50001]
PASS: Stats Passive Scan Rule [50003]
PASS: Insecure JSF ViewState [90001]
PASS: Java Serialization Object [90002]
PASS: Sub Resource Integrity Attribute Missing [90003]
PASS: Insufficient Site Isolation Against Spectre Vulnerability [90004]
PASS: Charset Mismatch [90011]
PASS: WSDL File Detection [90030]
PASS: Loosely Scoped Cookie [90033]
WARN-NEW: Re-examine Cache-control Directives [10015] x 2 
        https://localhost:8080 (200 OK)
        https://localhost:8080/robots.txt (200 OK)
WARN-NEW: Missing Anti-clickjacking Header [10020] x 1 
        https://localhost:8080 (200 OK)
WARN-NEW: X-Content-Type-Options Header Missing [10021] x 6 
        https://localhost:8080 (200 OK)
        https://localhost:8080/index.css (200 OK)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=console.png (200 OK)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=debugger.js (200 OK)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=style.css (200 OK)
WARN-NEW: Information Disclosure - Suspicious Comments [10027] x 3 
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=debugger.js (200 OK)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=debugger.js (200 OK)
        https://localhost:8080/login (500 Internal Server Error)
WARN-NEW: Strict-Transport-Security Header Not Set [10035] x 12 
        https://localhost:8080 (200 OK)
        https://localhost:8080/app/app.py (404 Not Found)
        https://localhost:8080/app/helper/db_manager.py (404 Not Found)
        https://localhost:8080/index.css (200 OK)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=console.png (200 OK)
WARN-NEW: Server Leaks Version Information via "Server" HTTP Response Header Field [10036] x 12 
        https://localhost:8080 (200 OK)
        https://localhost:8080/app/app.py (404 Not Found)
        https://localhost:8080/app/helper/db_manager.py (404 Not Found)
        https://localhost:8080/index.css (200 OK)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=console.png (200 OK)
WARN-NEW: Content Security Policy (CSP) Header Not Set [10038] x 8 
        https://localhost:8080 (200 OK)
        https://localhost:8080/app/app.py (404 Not Found)
        https://localhost:8080/app/helper/db_manager.py (404 Not Found)
        https://localhost:8080/login?btn=Confirm+Pin&pin=ZAP (404 Not Found)
        https://localhost:8080/sitemap.xml (404 Not Found)
WARN-NEW: Storable and Cacheable Content [10049] x 12 
        https://localhost:8080 (200 OK)
        https://localhost:8080/app/app.py (404 Not Found)
        https://localhost:8080/app/helper/db_manager.py (404 Not Found)
        https://localhost:8080/index.css (200 OK)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=console.png (200 OK)
WARN-NEW: Permissions Policy Header Not Set [10063] x 9 
        https://localhost:8080 (200 OK)
        https://localhost:8080/app/app.py (404 Not Found)
        https://localhost:8080/app/helper/db_manager.py (404 Not Found)
        https://localhost:8080/login?__debugger__=yes&cmd=resource&f=debugger.js (200 OK)
        https://localhost:8080/login?btn=Confirm+Pin&pin=ZAP (404 Not Found)
WARN-NEW: Source Code Disclosure - SQL [10099] x 1 
        https://localhost:8080/login (500 Internal Server Error)
WARN-NEW: Modern Web Application [10109] x 2 
        https://localhost:8080 (200 OK)
        https://localhost:8080/login (500 Internal Server Error)
WARN-NEW: Authentication Request Identified [10111] x 1 
        https://localhost:8080/login (500 Internal Server Error)
WARN-NEW: Absence of Anti-CSRF Tokens [10202] x 1 
        https://localhost:8080/login (500 Internal Server Error)
WARN-NEW: Application Error Disclosure [90022] x 1 
        https://localhost:8080/login (500 Internal Server Error)
FAIL-NEW: 0     FAIL-INPROG: 0  WARN-NEW: 14    WARN-INPROG: 0  INFO: 0 IGNORE: 0       PASS: 52

Enter fullscreen mode Exit fullscreen mode

Step 4: Retrieve the HTML Report

Once the scan is complete, an HTML report named scan-report.html will be saved in your current working directory. You can open this file in any web browser to view the detailed security scan report.

Here is the report it generates:

Scan Report - Generated for TIWAP

Your generated report can be shared with your teams to make the proper fixes required.

Additional Tips

  • Scan Duration: Depending on the complexity and size of your application, the scan may take some time. Ensure your application remains running until the scan is completed.
  • Security Considerations: Regularly update the Docker image with docker pull owasp/zap2docker-stable to ensure you are using the latest security checks and features.

Top comments (0)