Safeguard
AppSec

Dynamic Scanning, Explained for Engineers Who Aren't Security Specialists

Dynamic scanning tests a running application the way an attacker would, by sending it requests and watching what comes back. Here's what that actually involves and when it's the right tool.

Safeguard Team
Product
6 min read

Dynamic scanning tests your application the way an actual visitor, or an attacker, would: by sending it real HTTP requests against a running instance and observing the responses, rather than reading the source code that produced them. If you're an engineer who's mostly heard of "DAST" as a term security teams throw around without much explanation, this is the plain version of what it actually does and why it exists alongside code-level tools.

What actually happens during a dynamic scan?

A dynamic scanner starts by crawling or otherwise mapping your application's reachable surface, following links, submitting forms, or, for API-driven scans, working from an OpenAPI schema to enumerate endpoints. Once it has a map of what's reachable, it starts sending crafted inputs designed to probe for specific vulnerability classes: a SQL injection payload in a form field, a cross-site scripting payload in a query parameter, a request for an admin-only endpoint made without a valid session, and it evaluates whether the response indicates the application handled that input safely or not.

The key thing that makes this "dynamic" rather than "static" is that the scanner never looks at your source code at all. It doesn't know or care whether your codebase is Python, Java, or Go; it only cares about what comes back over the wire. That's both the strength and the limitation, discussed below.

What can dynamic scanning catch that code review can't?

Configuration and deployment issues are the clearest example. A missing security header, an overly permissive CORS policy, a TLS configuration accepting deprecated cipher suites, a verbose error page leaking a stack trace, none of these are bugs in your source code in any way a static analyzer would flag, because they're properties of how the application is deployed and configured, not how it's written. Dynamic scanning is often the only automated way to catch this class of issue before it reaches production, short of a manual configuration audit.

It also catches the actual, confirmed exploitability of an issue rather than a theoretical one. If a dynamic scan successfully injects a SQL payload and observes a database error or an unexpected data return, you have direct evidence the vulnerability is real and reachable in the live environment, not just a code pattern that looks risky on paper. This is valuable for prioritization: a confirmed, exploited-in-testing finding deserves faster remediation than a static-analysis flag that hasn't been confirmed to actually trigger.

What can it miss?

Anything not reachable through the interface the scanner is testing against. If a vulnerable code path requires a specific authenticated role the scanner wasn't configured with credentials for, or a multi-step workflow the scanner's crawler didn't discover, it simply won't be tested. Dynamic scanning is also generally weaker at attributing a finding to a specific line of code, because it only sees the external behavior, so a developer receiving a dynamic scan finding often has more work to do tracing it back to the responsible code than they would with a static analysis finding that points directly at the vulnerable line.

Coverage depends heavily on crawl or schema completeness. An application with significant client-side routing, or an API without a machine-readable schema, is harder for a dynamic scanner to map fully, and gaps in the map become gaps in test coverage that are easy to miss unless someone checks the scan's coverage report against the application's actual surface.

When should dynamic scanning run in your pipeline?

Because it needs a running, deployed target, dynamic scanning naturally happens later than static analysis, against a staging environment, a pre-production deployment, or occasionally production itself for lower-intensity, non-destructive scans. Running it against staging on every release candidate, rather than only periodically, catches regressions before they reach customers without needing to run a full scan on every single commit, which is often too slow for a per-PR gate.

Authenticated scanning, where the scanner is given valid credentials for one or more user roles, is worth the setup effort even though it's more work than an unauthenticated crawl, because a huge share of real vulnerabilities live behind a login, and an unauthenticated scan alone will systematically miss them.

How does this fit with other testing types?

Dynamic scanning is one layer in a broader application security testing program, and it's most effective paired with static analysis rather than used alone. Static analysis catches issues earlier and cheaper, before deployment, but can't confirm real-world reachability or catch configuration issues; dynamic scanning confirms exploitability and catches deployment-layer issues but runs later and has narrower attribution. Teams that run both, and correlate findings between the two, get a much more complete and better-prioritized picture than either alone.

FAQ

Is dynamic scanning the same thing as penetration testing?

Not quite. Dynamic scanning is automated and runs continuously or on a schedule, testing for known vulnerability patterns at scale. Penetration testing is manual, done by a human tester who can chain findings creatively and test business logic in ways automated tools can't, but it's periodic and much more expensive per hour of coverage.

Does dynamic scanning require the application to be in production?

No, and running it against production is often discouraged for anything beyond low-intensity, non-destructive checks. Staging or a dedicated test environment that mirrors production configuration is the standard target.

Can dynamic scanning test APIs, not just web pages?

Yes, and schema-driven API scanning is a distinct, increasingly common mode, working from an OpenAPI or GraphQL schema rather than crawling HTML links, since APIs don't expose the same kind of navigable page structure a traditional web crawler relies on.

Why does a dynamic scan sometimes miss a vulnerability that a manual tester finds in an hour?

Usually because the scan's crawl or schema mapping didn't reach the vulnerable page or endpoint, often because it required a multi-step workflow, a specific user role, or state the automated crawler didn't know how to set up. This is the main argument for periodic manual testing alongside automated dynamic scanning, not instead of it.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.