How to Use OWASP ZAP for Security Testing
ZAP is maintained by the OWASP Foundation and supported by a global community of contributors. It runs on Windows, macOS, and Linux, supports testing any web application regardless of the technology stack behind it, and is free for both personal and commercial use. Whether you are running your first security scan or building an automated testing pipeline, ZAP is a strong starting point because it costs nothing and covers the most common vulnerability categories automatically.
Install and Configure ZAP
Download ZAP from the official OWASP ZAP website (zaproxy.org). It requires Java 17 or later, which is bundled with the installer on most platforms. After installation, launch ZAP and decide on a session mode: Standard mode (default) allows active scanning, Protected mode restricts active scanning to explicitly scoped domains, and Safe mode disables anything that could modify the target application.
For manual testing, configure your browser to use ZAP as its HTTP proxy. ZAP listens on localhost port 8080 by default. In your browser's network settings, set the HTTP and HTTPS proxy to 127.0.0.1:8080. ZAP generates its own CA certificate for intercepting HTTPS traffic; you need to install this certificate in your browser's trust store to avoid SSL warnings on every page. In ZAP, go to Tools > Options > Network > Server Certificates and export the certificate, then import it into your browser's certificate manager as a trusted certificate authority.
For automated scans that do not need a browser proxy, ZAP can be started in daemon mode from the command line: zap.sh -daemon -port 8080. This starts ZAP headless, controlled entirely through its API or automation framework.
Explore the Application
Before scanning, ZAP needs to know what the application looks like. The most thorough approach is manual exploration: browse the application through ZAP's proxy, visiting every page, submitting every form, clicking every link, and exercising every feature. ZAP records every request and response, building a site tree in its left panel that represents the application's structure.
Manual exploration captures pages behind authentication, complex JavaScript-driven interfaces, and multi-step workflows that automated crawlers often miss. Take time to log in, navigate to authenticated areas, fill out forms with representative data, and exercise features that require specific state (adding items to a cart before checking out, creating a project before uploading files).
If the application uses an API, import the API specification (OpenAPI/Swagger, GraphQL schema) into ZAP through the Import menu. This gives ZAP a complete map of API endpoints without needing to discover them through the UI.
After manual exploration, check ZAP's site tree to verify that it includes all the areas you want to test. Any page or endpoint that appears in the tree will be included in subsequent scans. Anything missing will not be tested.
Run the Spider
ZAP's spider automatically crawls the application starting from a seed URL, following links, parsing forms, and discovering pages that manual browsing may have missed. Right-click the target site in the site tree and select Attack > Spider. Configure the spider scope to stay within the target domain (you do not want to crawl external sites).
ZAP includes two spiders: the traditional spider that follows HTML links and form actions, and the AJAX spider that uses a real browser (via Selenium or Playwright) to render JavaScript-heavy pages and discover dynamically generated content. For modern single-page applications built with React, Angular, or Vue, the AJAX spider finds pages that the traditional spider misses entirely because the content is rendered by JavaScript rather than present in the initial HTML.
Configure the AJAX spider by going to Tools > Options > AJAX Spider and selecting a browser (Firefox or Chrome). The AJAX spider is slower because it renders each page in a real browser, but for JavaScript-heavy applications it is essential. Running the traditional spider first and the AJAX spider second is the most efficient approach: the traditional spider maps the static structure quickly, then the AJAX spider fills in the dynamic content.
After the spider completes, review the site tree again. New pages and endpoints discovered by the spider will appear, expanding your testing coverage. Check for unexpected findings like admin panels, test pages, or backup files that should not be publicly accessible.
Run the Active Scanner
The active scanner is where ZAP actually tests for vulnerabilities. It sends thousands of modified requests to the application, each designed to trigger a specific vulnerability type. Right-click the target site and select Attack > Active Scan. Select the scan policy (Default covers the most common vulnerability types) and the scope (the site or a specific subtree).
The active scanner tests for SQL injection by sending SQL-specific characters and measuring response differences. It tests for XSS by injecting script payloads and checking whether they appear in responses. It tests for path traversal by including ../sequences in parameters. It checks for command injection, LDAP injection, XML injection, and dozens of other vulnerability types. Each test uses multiple payloads because different applications and frameworks handle input differently.
Active scanning takes time, from minutes for small applications to hours for large ones. ZAP's progress bar shows which scan rules are running and how many requests have been sent. You can monitor results in real-time in the Alerts tab, where findings appear as they are discovered.
Warning: Active scanning sends potentially destructive payloads to the application. It may create records, modify data, lock accounts, or trigger security alerts. Only run active scans against test or staging environments that you own and have permission to test. Never scan production systems without explicit authorization, and never scan systems you do not own.
Review and Triage Results
After the scan completes, ZAP's Alerts tab shows all findings organized by severity: High (red), Medium (orange), Low (yellow), and Informational (blue). Each alert includes the vulnerability type, the affected URL, the request that triggered it, the response, and a description with remediation advice.
Not every finding is a real vulnerability. ZAP errs on the side of reporting potential issues, which means some findings are false positives: things that look suspicious but are not actually exploitable. Review each finding critically:
For injection findings, examine the request payload and the response. Did the SQL injection payload actually change the database query's behavior (different results, error messages, time delays), or did the application safely reject or sanitize it? For XSS findings, check whether the injected script actually appears in the response in a context where a browser would execute it, or whether it was encoded or stripped.
Mark confirmed findings as true positives and document them with severity, reproduction steps, and remediation guidance. Mark false positives as such in ZAP (right-click > Mark as False Positive) so they do not reappear in future scans. This tuning process is ongoing: each scan produces fewer false positives as ZAP's configuration learns the application's behavior.
Export the findings as an HTML or XML report for sharing with development teams. ZAP's report templates provide developer-friendly output with clear descriptions and fix recommendations for each vulnerability type.
Integrate with CI/CD
ZAP's Docker image and automation framework make it straightforward to run security scans in CI/CD pipelines. The official ZAP Docker image (ghcr.io/zaproxy/zaproxy) includes everything needed to run scans from the command line without a GUI.
ZAP provides three built-in scan types as command-line scripts: the baseline scan (checks for passive issues only, fast and safe), the full scan (includes active scanning, thorough but slower), and the API scan (designed for REST, GraphQL, and SOAP APIs). Each accepts a target URL and produces a report.
For a GitHub Actions pipeline, a basic security scan step looks like running the ZAP Docker container with the target URL and outputting the report as a build artifact. If you need authenticated scanning, pass ZAP an authentication script or use the automation framework with a YAML configuration that includes login steps.
The automation framework is ZAP's most powerful CI/CD integration. It uses a YAML plan file that defines the environment (target URL, authentication), the job (spider, active scan, passive scan), and the reporting (threshold for pass/fail, report format). Plans can include custom scan policies, alert filters to suppress known false positives, and authentication configurations for testing behind login forms.
Set the pipeline to fail on high-severity findings and warn on medium findings. This provides a security gate without blocking every deployment on informational notices. Over time, tighten the threshold as the team addresses its backlog of findings.
ZAP for Authenticated Scanning
Most real applications require authentication to test their most important functionality. ZAP supports multiple authentication methods: form-based login (submitting credentials to a login form), script-based authentication (using a custom script for complex login flows), JSON-based authentication (posting credentials to an API endpoint), and manual authentication (using the browser proxy to log in manually and let ZAP capture the session).
For browser-based authentication, ZAP integrates with Selenium and Playwright. A script that navigates to the login page, enters credentials, and submits the form runs before the scan starts, establishing a session that ZAP uses for all subsequent requests. This approach handles complex login flows including multi-factor authentication, CAPTCHA bypass (on test environments), and OAuth redirects.
Configure ZAP's session management to recognize session tokens (cookies, headers, or URL parameters) and to detect when a session expires. Set a logged-in indicator, a string that appears in responses only when authenticated (like a username or logout link). When ZAP detects that the indicator has disappeared, it re-authenticates automatically, keeping the scan running without interruption.
ZAP Scan Policies
Scan policies control which tests ZAP runs and how aggressively. The default policy covers the most common vulnerability types at a moderate intensity. Custom policies let you tune the scan for your application's specific needs.
Create a custom policy when the default scan takes too long (disable tests that are not relevant to your technology stack), produces too many false positives (lower the strength of aggressive tests), or misses application-specific issues (add custom scan rules). Save policies and share them with your team so everyone runs consistent scans.
ZAP distinguishes between passive scanning (analyzing existing traffic without sending additional requests, always safe) and active scanning (sending crafted requests to probe for vulnerabilities, potentially disruptive). In CI/CD pipelines, some teams run only passive scans on every deployment and active scans on a weekly schedule, balancing thorough testing with pipeline speed.
Common ZAP Findings and What They Mean
Missing Anti-CSRF Tokens: Forms that modify data (create, update, delete) should include a CSRF token that the server validates. Without it, an attacker can craft a page that submits the form on behalf of a logged-in user. Fix by implementing CSRF tokens in your framework (most modern frameworks include this by default).
X-Frame-Options Header Not Set: Without X-Frame-Options or a CSP frame-ancestors directive, the page can be embedded in an iframe on a malicious site, enabling clickjacking attacks. Fix by adding the header to your server configuration: X-Frame-Options: DENY or X-Frame-Options: SAMEORIGIN.
Content-Security-Policy Header Not Set: Without CSP, the browser allows any script to execute on the page, making XSS attacks more impactful. Fix by defining a CSP that restricts script sources to trusted origins. Start with a report-only policy to identify what would break before enforcing.
Cookie Without HttpOnly Flag: Cookies accessible to JavaScript can be stolen through XSS attacks. Session cookies should always be HttpOnly so client-side scripts cannot read them. Fix in your server's cookie configuration.
SQL Injection: ZAP detected that a SQL payload changed the application's response behavior, indicating that user input reaches a database query without sanitization. Fix by using parameterized queries or prepared statements for all database access.
OWASP ZAP provides free, thorough security scanning for web applications. Start with manual exploration through ZAP's proxy to build coverage, run the spider to discover more content, use the active scanner to test for vulnerabilities, and integrate ZAP into your CI/CD pipeline using its Docker image and automation framework for continuous security testing.