Why “Non-Intrusive” Matters in Security Audits
Security testing often conjures images of aggressive scans that slow down servers, flood logs, and risk service instability. But it doesn’t have to be that way. With OWASP ZAP (Zed Attack Proxy), you can conduct effective, ethical, and low-impact audits that fit neatly into your day-to-day development and operations workflows.
A non-intrusive audit focuses on safe techniques—primarily passive scanning and controlled exploration—that uncover a wide range of issues (like missing security headers, cookie misconfigurations, and information leakage) without generating heavy load or sending potentially harmful payloads. This approach is ideal for:
- Early-stage testing in development and staging environments
- Continuous security checks in CI/CD
- Quick production verifications under strict change-control policies
- Vendors and partners who require minimal risk to live services
Below, you’ll learn how to design and run non-intrusive security audits with OWASP ZAP, step by step, with practical configurations, real-world examples, and workflow tips. If you have explicit authorization to test a given target, such as your own site or a sanctioned testing endpoint (e.g., https://www.web-psqc.com/security/scan), you can follow along and adapt the guidance to your environment.
Note: Only test systems for which you have explicit permission. Even “lightweight” scans can be unwanted or unlawful on unauthorized targets.
OWASP ZAP in a Nutshell
OWASP ZAP is a free, open-source web application security scanner maintained by the Open Worldwide Application Security Project. It sits as a proxy between your browser and target site, capturing HTTP(S) traffic, analyzing it, and—if configured—performing automated checks.
Key ZAP features for non-intrusive audits:
- Passive Scanner: Observes traffic and raises alerts without sending additional requests or payloads.
- Spider and AJAX Spider: Enumerates site content by following links (with adjustable limits).
- Contexts and Scope: Precisely define what is in scope, what to exclude, and how authentication works.
- Heads Up Display (HUD): In-browser overlay that highlights issues as you browse.
- Docker-based Baseline Scan: A passive scanning CLI suited to CI/CD without risky active tests.
ZAP supports four modes:
- Safe Mode: No potentially dangerous actions. Perfect for non-intrusive work.
- Protected Mode: Only acts on in-scope targets. Good for controlled testing.
- Standard Mode: Full functionality.
- Attack Mode: Aggressive automation; not recommended for production.
For non-disruptive audits, stick to Safe or Protected modes and primarily use passive scanning approaches.
Principles of Non-Intrusive Security Auditing
- Get explicit permission and define scope: Document which hosts, subdomains, and paths are in scope. Exclude others.
- Prefer passive techniques: Use ZAP passive scanning and manual exploration to surface a broad spectrum of issues.
- Rate-limit and throttle: Keep request rates low to avoid performance impact and alert fatigue.
- Avoid state-changing and destructive actions: Don’t fuzz or brute-force forms in production; turn off forced browsing and high-risk active rules.
- Communicate: Tell stakeholders when you’re testing, what you’re scanning, and at what intensity.
- Log responsibly: Minimize collection of sensitive data. Protect ZAP session data and reports.
- Start small: Crawl a modest set of pages first, then expand gradually if no instability appears.
Environment Setup and Safety Controls
Install ZAP
- Desktop GUI: Download from the OWASP ZAP website for your OS.
- Docker: Pull owasp/zap2docker-stable for containerized runs (ideal for pipelines).
Configure Safe Defaults
- ZAP Mode: Set to Safe or Protected via the top bar or Options.
- Scope: Add only authorized domains to Context. Explicitly exclude admin endpoints, file uploads, or high-risk paths on production.
- Request Throttling: Options -> Connection -> set “Concurrent Connections” low (e.g., 1–2) and add a request delay (e.g., 250–500 ms).
- Max Spider Limits: Keep shallow depth, low thread count, and short duration (e.g., 2–5 minutes) for initial passes.
- Passive Scanning Only (to start): Do not run active scans on production unless explicitly approved.
Browser Proxy Setup
- Set your browser to use ZAP as an HTTP/HTTPS proxy (default: 127.0.0.1:8080).
- Import ZAP Root CA into the browser to avoid HTTPS warnings (ZAP -> Tools -> Options -> Dynamic SSL Certificates).
- Use a dedicated browser profile to avoid mixing personal sessions or cached data.
Protect Sensitive Data
- Use a low-privilege test account for authenticated checks.
- Clear or disable caching credentials in ZAP history when possible.
- Consider using an allowlist IP for testing to avoid triggering security systems without notice.
Scoping with Contexts: Precision Is Protection
Defining a Context is how you keep ZAP laser-focused and safe.
- Right-click the target in the Sites tree (or add it manually) and choose “Include in Context.”
- Set Include regex patterns (e.g., https://www.example.com/.*).
- Add Exclude patterns for:
- Admin areas (e.g., /admin/.*)
- Sensitive endpoints (e.g., /payment/.*)
- File upload or heavy endpoints (e.g., /media/upload)
- Under Context -> Technology, deselect technologies you don’t use to reduce noise (e.g., if not using Java, uncheck it).
- If performing authenticated passive exploration, configure Authentication (login URL, parameters) and a Login Indicator (e.g., regex like “Logout” or a session cookie presence).
This scoping is what makes Protected Mode viable—you can browse safely, knowing ZAP won’t step out of bounds.
A Passive-First Workflow You Can Trust
The essence of a non-intrusive audit is: explore the site normally, let ZAP observe, and then triage the findings.
Option 1: Manual Explore with HUD (GUI)
- Set ZAP to Safe or Protected Mode.
- Start the HUD: Quick Start -> Manual Explore.
- Enter the in-scope URL (e.g., if authorized: https://www.web-psqc.com/security/scan).
- Navigate like a typical user: log in (if allowed), open key pages, submit harmless filters, and view account settings.
- ZAP’s Passive Scanner will analyze responses and highlight issues in the HUD without sending extra requests.
Tips:
- Visit representative pages covering layout templates, authenticated and unauthenticated views, and error pages.
- Avoid forms that trigger state changes (e.g., “delete,” “update,” “checkout”) on production.
Option 2: Conservative Spidering
The Spider follows links to discover pages. Configure it conservatively:
- Scope: In-scope only, no out-of-scope.
- Max Depth: 2–3.
- Max Children: 100–300.
- Duration: 2–5 minutes for an initial pass.
- Threads: 1–2.
- Respect robots.txt: Enabled, unless your testing policy says otherwise.
Run the Spider on your Context after manual browsing. This discovery helps passive scanning reach more pages with minimal impact.
Option 3: AJAX Spider for SPAs
For single-page apps, the AJAX Spider can trigger more content to load:
- Run only after initial manual exploration.
- Keep a short duration and low thread count.
- Only run in staging or with explicit production approval, because SPAs may fire background requests more aggressively.
Option 4: Docker Baseline Scan (CI/CD-Friendly)
The Baseline Scan performs passive checks against a target, generating a report without active attacks. If you’re authorized to test, you can run something like:
docker run --rm -t \
owasp/zap2docker-stable zap-baseline.py \
-t https://www.web-psqc.com/security/scan \
-m 5 \
-r zap-baseline-report.html \
-d \
-z "-config spider.maxDuration=3 -config connection.requestTimeoutInSecs=15 -config spider.threadCount=1"
What it does:
- -t sets the target.
- -m sets maximum acceptable risk level for failures (0–3).
- -r outputs an HTML report.
- -d enables debug logging (optional; remove for quieter runs).
- -z passes ZAP config overrides to further limit activity.
This approach is ideal for non-intrusive periodic checks in your pipeline or as a pre-deployment gate in staging.
Authentication Without Breaking Things
Authenticated testing is often crucial and can be done gently:
- Use a dedicated test account with minimal privileges.
- Configure Context Authentication: Choose Form-based, HTTP-based, or Script-based as appropriate.
- Set a reliable Login Indicator: A regex that appears only when logged in (e.g., “Logout” or a user menu).
- Session Management: Cookies are typical; record which cookies indicate auth state.
- Do not brute-force logins or attempt session invalidation in production.
- Keep the manual exploration approach: sign in, browse key pages, and let passive checks run.
For CI/CD, consider:
- Injecting credentials via environment variables.
- Using short-lived tokens or ephemeral test users where possible.
- Running authenticated baseline scans only in staging unless there’s a contractual need for production.
Tuning ZAP to Be “Good Neighbor” Quiet
If you need tighter control, adjust these levers:
- Connection Limits: Options -> Connection -> set “Concurrent Connections per Host” to 1 and add a per-request delay (e.g., 200–500 ms).
- Passive Scan Rules: Install official passive add-ons (pscanrules) for better coverage; disable any noisy alpha/beta rules if they create false positives.
- User-Agent: Use a standard browser User-Agent to avoid triggering special responses from WAF/CDN.
- Exclude URLs and Parameters: Options -> Global Exclude URL and Context -> Exclude to omit logout links, heavy downloads, GraphQL introspection on production, or expensive endpoints.
- Policy Thresholds: Set Alert Threshold to Medium or High for less noise and fewer fire drills during early phases.
The aim is to keep your footprint small and predictable.
Interpreting Results: What Passive Scans Surface Best
Passive scanning excels at identifying misconfigurations and missing hardening. Common findings and how to act on them:
-
Missing Security Headers
- Strict-Transport-Security (HSTS): Enforce HTTPS via HSTS with preload where appropriate. Example: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
- Content-Security-Policy (CSP): Mitigate XSS and injection by restricting sources. Start with a report-only policy, then enforce.
- X-Frame-Options or CSP frame-ancestors: Prevent clickjacking. Example: X-Frame-Options: DENY
- X-Content-Type-Options: nosniff to block MIME-type sniffing.
- Referrer-Policy: Reduce sensitive referrer leakage (e.g., no-referrer or strict-origin-when-cross-origin).
- Permissions-Policy: Limit powerful browser features (camera, geolocation, etc.).
-
Insecure Cookies
- Missing Secure: Ensure session cookies are set with Secure for HTTPS-only.
- Missing HttpOnly: Block client-side scripts from reading cookies.
- Missing SameSite: Set Lax or Strict to mitigate CSRF risks.
- Overly long TTLs: Shorten sensitive cookie lifetimes.
-
Information Leakage
- Server banners and X-Powered-By: Strip or normalize to avoid fingerprinting.
- Verbose error pages: Replace with generic messages; log details internally.
- Directory listings: Disable unless needed.
-
TLS and Mixed Content
- Mixed HTTP/HTTPS content: Serve all resources over HTTPS.
- Weak ciphers/protocols bannered in headers: Ensure modern TLS settings; use a TLS scanner for deeper checks.
-
CORS Misconfigurations
- Access-Control-Allow-Origin: * combined with credentials: risky; set explicit origins and avoid credentials with wildcard.
- Overly permissive methods/headers: Lock down to what you need.
-
Cache Control
- Sensitive pages lacking no-store/no-cache: Prevent caching of authenticated or sensitive content.
-
Redirect Behavior
- Open redirects are typically active-scan territory, but passive checks may flag unsafe patterns. Validate and sanitize redirect parameters.
Each alert includes evidence and references. Use that to prioritize fixes. High risk, low effort items—like setting headers—are quick wins that reduce exposure immediately.
Practical Example: A Minimal-Impact Audit Flow
Assuming you’re authorized to test your target (e.g., https://www.web-psqc.com/security/scan), here’s a conservative sequence:
-
Preparation
- Confirm written authorization, scope, and maintenance windows.
- Set ZAP to Safe Mode.
- Create a Context: Include only https://www.web-psqc.com/security/scan and carefully exclude admin/upload paths if present.
-
Manual Explore
- Use HUD to manually browse 10–20 core pages.
- If auth is in scope, log in with a test account and visit typical screens (dashboard, profile, read-only views).
- Avoid actions that create, modify, or delete real data on production.
-
Conservative Spider (Optional)
- Run a spider limited to depth 2–3, thread count 1, and a max of 3 minutes.
- Monitor server responsiveness. Stop early if you see instability.
-
Review Passive Alerts
- Open the Alerts tab, group by risk, and begin triage.
- Export a report (HTML/XML/JSON) for tracking.
-
Quick Fixes and Re-Check
- Add security headers, lock down cookies, and remove noisy banners.
- Rerun manual explore or a baseline scan to confirm improvements.
-
CI/CD Integration
- Add a nightly or on-merge zap-baseline.py run in staging.
- Fail the job on High alerts; warn on Medium; track Low and Informational.
This approach keeps your testing unobtrusive while still surfacing issues that materially improve your security posture.
CI/CD Integration: Baseline by Default
Non-intrusive scanning fits perfectly into continuous delivery. A sample GitHub Actions job:
name: ZAP Baseline
on:
workflow_dispatch:
schedule:
- cron: "0 3 * * *"
jobs:
zap-baseline:
runs-on: ubuntu-latest
steps:
- name: ZAP Baseline Scan (Passive)
run: |
docker run --rm -t \
-v "$(pwd):/zap/wrk" \
owasp/zap2docker-stable zap-baseline.py \
-t https://staging.example.com \
-m 2 \
-r zap-report.html \
-d \
-z "-config spider.maxDuration=5 -config spider.threadCount=1 -config connection.requestTimeoutInSecs=20"
- name: Archive Report
uses: actions/upload-artifact@v4
with:
name: zap-report
path: zap-report.html
Recommendations:
- Run in staging by default; use production only with explicit approval.
- Use a rules file to ignore known, low-risk findings you’ve acknowledged; revisit periodically.
- Keep the bar reasonable: fail on High, warn on Medium, and report Low/Info for trend analysis.
- For APIs, use zap-api-scan.py with your OpenAPI/Swagger spec, still in passive-first mode where possible.
Troubleshooting and Non-Intrusive Guardrails
- HTTPS Issues
- If the browser warns about certs, import ZAP’s root CA. For headless scans, use the -z flags to loosen SNI or handshake constraints only if safe and approved.
- Authentication Flakiness
- Validate login indicators and session cookies. Avoid aggressive spidering that logs you out by hitting logout links—exclude them from scope.
- SPA Coverage
- Use HUD and AJAX Spider sparingly. If your SPA loads a lot of background requests, shorten durations.
- WAF/CDN Interference
- Rate-limit further. Add your testing IP to an allowlist if policies permit.
- No Findings Doesn’t Mean No Risk
- Passive scans are conservative; they won’t detect everything (e.g., complex logic flaws). They’re a foundation, not the finish line.
When and How to Add Light Active Testing (With Permission)
While this guide focuses on non-intrusive auditing, there are scenarios where carefully constrained active checks are warranted—ideally in staging:
- Limit Rule Set: In ZAP’s Active Scan policy, disable high-risk payloads and intrusive categories. Keep to low-impact rules.
- Narrow Scope: Target a small set of high-value pages rather than the entire site.
- Throttle Aggressively: Single-threaded, with delays between requests.
- Maintenance Window: Coordinate with ops; monitor metrics and logs.
If you’re on production, avoid active scans unless there’s a contractual requirement and you have explicit go-ahead, rollback plans, and live monitoring.
Practical Remediation Playbook
Map common findings to quick, actionable fixes:
-
Add Core Headers
- HSTS: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload (after validating readiness for preload)
- CSP: Start with Content-Security-Policy-Report-Only: default-src 'self'; then refine and enforce CSP
- X-Frame-Options: DENY or implement frame-ancestors in CSP
- X-Content-Type-Options: nosniff
- Referrer-Policy: strict-origin-when-cross-origin or no-referrer
- Permissions-Policy: e.g., camera=(), geolocation=(), microphone=()
-
Harden Cookies
- Set Secure and HttpOnly on session cookies.
- Add SameSite=Lax by default; SameSite=Strict for highly sensitive flows.
- Rotate session IDs on login and privilege escalation.
-
Reduce Information Leakage
- Remove or standardize Server and X-Powered-By headers.
- Return generic error pages; log detail server-side only.
- Disable directory listing on web servers.
-
Improve TLS Hygiene
- Redirect HTTP -> HTTPS everywhere.
- Use modern TLS versions and ciphers; consider automated cert renewal.
-
Tighten CORS
- Replace wildcard origins with an explicit allowlist.
- Avoid Access-Control-Allow-Credentials: true unless strictly required.
-
Cache Control
- Add Cache-Control: no-store, no-cache for authenticated/sensitive routes.
- Control ETags and vary headers appropriately.
Lightweight Reporting That Teams Actually Use
- Executive Summary: One page with risk trends and top issues.
- Technical Appendix: Full ZAP report plus reproductions and remediation guidance.
- Ticketing Integration: Create issues automatically for High and Medium findings with links to evidence.
- SLAs and Owner Assignment: Tag services/teams so fixes land with the right people quickly.
- Before/After Diffs: Re-run the baseline after changes and highlight what improved.
The goal is not just to find issues—it’s to fix them without derailing delivery.
A Non-Intrusive Audit Checklist
- Authorization and scope documented
- ZAP in Safe or Protected Mode
- Context created with include/exclude patterns
- Throttling and concurrency limits set
- Manual explore with HUD completed
- Conservative spider run (optional)
- Passive findings reviewed and prioritized
- Quick wins (headers, cookies, CORS) applied
- CI/CD baseline scan configured in staging
- Reports archived; tickets created for High/Medium
- Periodic re-scan scheduled and tracked
Frequently Asked Questions
-
Will passive scans miss serious issues?
- Passive scans won’t find everything, especially complex injection and logic flaws. They’re an excellent, low-risk baseline. Add targeted, authorized active tests in staging to go deeper.
-
Can I run this in production?
- Yes, if you use Safe/Protected Mode, throttle requests, and stick to passive scanning. Communicate with stakeholders and confirm maintenance windows for large sites.
-
How often should I re-scan?
- At minimum, after significant releases and monthly baselines. Many teams run daily or nightly passive scans in staging for fast feedback.
-
What about APIs?
- Use zap-api-scan.py with your OpenAPI spec for non-intrusive, spec-driven discovery. Keep it passive-first in production.
Final Thoughts
Non-intrusive audits with OWASP ZAP help teams build security into the everyday workflow—finding misconfigurations, missing headers, unsafe cookies, and information leaks without disrupting users or overloading systems. Start with Safe Mode and passive scanning, establish tight scope and throttling, and wire ZAP Baseline into your CI/CD. As your maturity grows, carefully introduce targeted active checks in staging.
With a disciplined, low-impact approach, you’ll raise your security bar, reduce firefighting, and keep your delivery cadence intact.