SAST vs DAST: static code analysis or testing the running app

SAST reads source code for flaws; DAST attacks a running app from outside. What each finds and misses, example configs, and where each sits in CI.

Short answer

Run SAST on every pull request: it is fast, points at the exact line and catches injection sinks, unsafe APIs and hard-coded secrets before merge. Run DAST against a deployed staging environment: it finds what only exists at runtime, such as missing headers, auth and session flaws, misconfiguration and exploitable behaviour, but it cannot see code it does not reach. They are complements, not alternatives, and neither covers vulnerable dependencies (that is SCA) or business logic flaws like broken object-level authorisation without help.

SASTDAST
TestsSource, bytecode or binaries at restA running application over HTTP
ViewWhite boxBlack box
WhenPre-merge, in the IDE and PRPost-deploy, staging or pre-prod
Finds wellInjection sinks, unsafe APIs, weak crypto calls, secretsHeaders, TLS, auth and session issues, misconfig, reflected XSS
MissesRuntime config, deployment, infraUnreached code, deep logic, anything behind auth it cannot log into
Result points toFile and lineURL, parameter and request
False positivesHigher, needs tuningLower when exploit is confirmed
SpeedSeconds to minutes (diff scans)Minutes to hours
Language dependencyPer language and frameworkLanguage agnostic
Example toolsSemgrep, CodeQL, SonarQubeZAP, Burp Suite DAST, Nuclei

01How each works

SAST parses code into a syntax tree and, in better tools, a data flow graph. Taint analysis tracks untrusted sources (request parameters, headers) to dangerous sinks (SQL execution, shell, HTML output) and reports paths that skip a sanitiser. Because it never runs the code it sees every branch, including dead ones, which is why it over-reports.

DAST crawls or imports an API spec, then sends crafted requests (payloads for injection, XSS, path traversal, SSRF) and judges responses. A passive scan only inspects normal traffic for issues like missing headers; an active scan attacks. It only sees what it can reach, so authenticated coverage depends on giving it a working login and a spec.

iIAST and SCA

IAST instruments the running app so a test hit can be traced to a code line, combining both views. SCA checks third-party dependencies against vulnerability databases. A sensible pipeline has SAST, SCA and secrets scanning on PRs and DAST on deploy.

02Hunting SQL injection both ways

SAST: Semgrep taint rule, run with semgrep --config rules/ on the PR diffyaml
rules:
  - id: express-sqli-taint
    languages: [javascript, typescript]
    severity: ERROR
    message: Request data reaches a SQL query. Use parameterised queries.
    mode: taint
    pattern-sources:
      - pattern: req.query.$P
      - pattern: req.body.$P
      - pattern: req.params.$P
    pattern-sanitizers:
      - pattern: Number(...)
    pattern-sinks:
      - patterns:
          - pattern: $DB.query($SQL, ...)
          - focus-metavariable: $SQL
DAST: ZAP API scan in CI after deploy to stagingbash
# Active DAST against staging, driven by the OpenAPI spec
docker run --rm -v "$(pwd):/zap/wrk:rw" -t ghcr.io/zaproxy/zaproxy:stable \
  zap-api-scan.py \
    -t https://staging.example.com/openapi.json \
    -f openapi \
    -r zap-report.html \
    -c zap-rules.conf   # per-rule IGNORE / WARN / FAIL for the CI gate

The Semgrep rule flags db.query("SELECT ... " + req.query.id) at the line, even on an endpoint nobody has deployed yet. ZAP flags the same bug only if the endpoint is in the spec, reachable and authenticated, but when it does, it shows a request that actually changed the response.

03When to pick which

  • Need feedback before merge: SAST, scoped to the diff so PR scans stay under a few minutes.
  • Need to prove the deployed thing is safe (headers, TLS, cookies, auth flows): DAST.
  • Polyglot estate or third-party apps without source: DAST, it does not care about the language.
  • Compliance asks for both (PCI DSS 6.2.4 and 11.3 style evidence, SOC 2 controls): run both and keep reports.
  • Limited budget: start with SAST plus SCA and secrets scanning on PRs, add a ZAP baseline on staging, then grow to authenticated active scans.

04Common mistakes

  • Turning on every SAST rule and failing builds on all of them. Developers learn to ignore it. Start with a small high-confidence set and block only on those.
  • Running DAST unauthenticated and calling the app covered. Most attack surface sits behind login.
  • Pointing an active DAST scan at production. It submits forms, creates records and can trigger alerts or outages.
  • Expecting either to find broken object-level authorisation. Neither knows that user A must not read user B's order; write tests for it.
  • Not baselining. Import existing findings as accepted debt so new PRs are judged only on what they introduce.

05How to say it in an interview

“How to say it in the room

SAST reads the code without running it, so it is fast, sees every path and points at the line, but it over-reports and is blind to runtime config. DAST attacks the running app from outside, so its findings are real and language agnostic, but it only tests what it can reach. I put SAST, SCA and secrets scanning on every PR with a small blocking rule set, and run authenticated DAST against staging on each deploy, never active scans on production.

Questions people ask

Q1Is SAST or DAST better?+

Neither. SAST finds flaws early with exact locations; DAST confirms exploitable issues in the deployed app and catches config problems SAST cannot see. Mature programmes run both.

Q2Which has more false positives?+

SAST, because it reasons about every path including ones that cannot be reached at runtime. DAST false positives exist (for example time-based checks on slow endpoints) but a confirmed DAST finding is usually real.

Q3Can DAST run in CI?+

Yes. A passive baseline scan fits in a few minutes after deploy to an ephemeral or staging environment. Full active scans take longer, so many teams run them nightly with the baseline as the PR gate.

Q4What is the difference between SAST and SCA?+

SAST analyses the code you wrote. SCA inventories third-party packages and matches versions against known vulnerabilities and licences. You need both; most breaches through dependencies are invisible to SAST.

Q5What is IAST?+

Interactive application security testing instruments the app at runtime, so when tests or a DAST scan exercise a route, the agent sees the data flow and reports the vulnerable line. It gives fewer false positives but needs a supported runtime and good test coverage.

Go deeper

Terms on this page