Skip to main content

Scanning production safely

DAST is a write-path tool by default. Left on defaults and pointed at production, the scanner will submit forms, mutate records, and trigger side-effects. This page is the single reference for running against production without breaking it.

Default: scan staging, not prod

Run DAST against a staging or pre-prod environment whenever possible. The rest of this page assumes you've decided, with eyes open, that you must scan production.

What the scanner actually sends​

Understand the traffic profile before you flip this on in prod:

PhaseWhat goes on the wireProd-safe?
Crawl (standard / hybrid)GET requests on every discoverable link; follows redirects; loads JS and clicks interactive elements.Mostly — same as a logged-in user browsing.
Crawl (ai / hybrid with ai_form_filling)LLM-filled form submissions (POST, PUT, PATCH). Can create accounts, comments, orders.No — turn off ai_form_filling for prod.
Passive scanResponse-only analysis; no extra requests beyond the crawl.Yes.
Active scanInjection payloads (XSS, SQLi, SSRF, path traversal, command injection, …) in query strings, bodies, headers, and paths. Sends many requests per endpoint.No — disable active testing in prod.
CVE scan (cve.js, cve.dom)Fingerprinting requests and DOM inspection only.Yes.

Passive + CVE only, no active injection, no AI form filling, explicit exclude list:

# levo-dast.yml
version: "1"
name: "acme-webapp"
env: "production"

target:
url: "https://app.example.com"
ignore_third_party: true
exclude_domains:
- "billing.example.com" # never touch payment flows
- "admin.example.com"

crawl:
type: "standard" # not ai / hybrid
ai_form_filling: false
max_depth: 3
max_pages: 150

scan:
enable_passive: true
enable_active: false # the load-bearing line
enable_websocket: false

cve:
js: true
dom: true

reporting:
output: "sarif"
output_file: "reports/prod.sarif"
severity: "medium"

Run as a read-only account:

shadownet scan --config levo-dast.yml --token "$READONLY_API_TOKEN"

If you must run active tests in prod​

Only if all of the following are true:

  1. You've isolated a staging-equivalent tenant in prod (separate org/workspace) that the scan account can only see.
  2. Writes from that tenant can't leak to customer-visible state.
  3. You have a rollback plan (database snapshot, feature flag) and a person on call.

Even then:

  • scan.attack_strength: "low" — not medium/high/insane.
  • scan.max_payloads: 25 — cap blast radius per endpoint.
  • scan.active_delay_ms: 200 — rate-limit yourself.
  • Narrow scan.http_methods to ["GET", "POST"] unless you have a specific reason.
  • Disable categories that mutate: path_traversal, command_injection, and anything else you haven't reviewed.
  • Run off-peak and watch your error-rate dashboard live.

Scan account hygiene​

  • Dedicated service account — never a human's credentials.
  • Least privilege — the account sees only the endpoints you want tested.
  • No prod admin role — even "read-only admin" often has write-shaped endpoints (e.g., DELETE /sessions/:id).
  • Rotate the token after every scan, or put it on a short TTL.

Rate-limit and WAF coordination​

  • Add the scanner's source IP (or your worker's egress IP) to an allowlist.
  • Tell your WAF vendor a scan is running — some detect payloads as an attack and auto-block the source.
  • If you hit rate limits, lower scan.max_payloads, crawl.max_pages, and raise scan.active_delay_ms.

Running from a worker in prod​

If you can't open your prod network to Levo's cloud runner, deploy a Kubernetes worker or a Docker worker inside the prod VPC. It pulls jobs outbound, so no inbound firewall change is needed.

Next​

Was this page helpful?