← All guides

DAST: Dynamic Application Security Testing

Running services
On this page

In plain terms

Dynamic Application Security Testing (DAST) tests your application while it's running, by making real HTTP requests to it. The way an attacker would. Where SAST reads the source code from the inside, DAST probes the live app from the outside, with no knowledge of the code. It's the difference between reviewing a building's blueprints and walking the halls rattling doorknobs.

Why it matters

Some vulnerabilities only exist when everything is wired together and running: a reflected cross-site scripting (XSS) flaw that depends on how a response is rendered, an authentication flaw, a misconfigured endpoint that leaks data, a debug page left exposed. Static analysis can't see these because they emerge from behavior, not code shape. DAST catches the runtime reality.

Where it fits

  • Artifact: a running endpoint, ideally a preview or staging deployment.
  • Stage: after deploy (to a non-production environment), or on a schedule. It's heavier and slower than PR-time checks, and it needs something running.

Passive vs. active, an important safety note

  • Passive/baseline scanning crawls the app and inspects responses. It's non-destructive and safe to run against your own site.
  • Active scanning attacks the app, injecting payloads, submitting forms, which can create data or cause side effects. It's powerful but must only be run against systems you own, with authorization. It's not something to drop into a default CI gate.
Which of a scanner's effects Draugr will not run without consent Effects are grouped into two bands. Sending traffic to the target and disclosing information about it to a third party are recorded in the report but not blocked, because the controls that do them exist to do them and a prompt for the thing a control is for becomes a keystroke people learn to skip. Creating or changing something that outlives the scan, and requiring access beyond what reading the target needs, are refused unless the descriptor lists them, and the refusal names what would have happened. A SCANNER THAT DOES MORE THAN READ SHOULD HAVE TO SAY SO In Draugr each of these is an effect a scanner declares, and two of the four do not run until a descriptor accepts them. RECORDED, AND IT RUNS network sends traffic to the target rather than reading an artifact disclosure sends information about the target to a third party consent is the line REFUSED UNLESS THE DESCRIPTOR SAYS SO mutate creates or changes something that outlives the scan privilege needs access beyond what reading the target requires
A Draugr scan that has not been permitted to change something stops before it does, and the refusal names what it would have done. Passive against active becomes a line a pull request reviews and every pipeline applies identically, rather than something whoever wrote the workflow has to remember.
ToolNotes
OWASP ZAPOSS, the reference DAST; full spider + passive/active scans (container-delivered)
NucleiOSS, single binary; fast template-based runtime checks (exposures, misconfigs)
WapitiOSS; active crawl-and-inject scanner
Burp Suite, StackHawk, DetectifyCommercial DAST platforms

Common pitfalls

  • Coverage depends on crawling. A DAST tool can only test what it can reach; single-page apps and authenticated areas need configuration to scan properly.
  • False positives and runtime cost. DAST is slower and noisier than static checks, reserve it for staging, not every PR.
  • Authorization. Only ever scan systems you're permitted to; active scanning especially.
How Draugr fits. The dast control ships today, backed by Nuclei, a single binary with no container to stand up, checking each host on every release.

By default it checks the unauthenticated perimeter: what any stranger can reach. Give the host an auth: block naming the environment variable that holds a token, set DRAUGR_TOKEN_ENVS to that variable's name in the pipeline, and it scans as a user instead. Point it at an openapi.yaml and it exercises the routes the API declares rather than crawling for them, read-only unless you name the write methods you accept. Both are in the Saga reference, under authenticating a dynamic scan and scanning an API from its specification.

A scanner that would do more to a target than read it has to declare that, and config.allowEffects is where a descriptor accepts it. A scan that has not been permitted to change something stops before it does, and the refusal says what it would have done. That is the passive-against-active distinction turned into something a descriptor states and a run enforces, rather than something a person has to remember when they change a target. The native headers control keeps ownership of HTTP security-header checks, and tls covers the transport.

Keep learning