L5 · Non-functional depth
L5Go deeper6 min read

SAST, DAST and SCA in the pipeline

Automated scanning of the code, the running app and the dependencies. The practical skill is triage — most findings are noise, and a team that cannot separate the real ones stops reading the reports entirely.

Most QA teams treat security scanning as a checkbox: run one tool, get a report, move on. That approach misses most real vulnerabilities, because no single scan type sees the whole application. A SQL injection bug in your own code, a live authentication flaw in your running service, and a known CVE in a dependency you imported last month are three different problems.

Each needs a different kind of scanner to catch it. Understanding SAST, DAST, and SCA, and where each one fits in your CI/CD pipeline, turns security testing from a compliance exercise into something that actually stops bugs before release.

What SAST catches

Static Application Security Testing reads your source code without running it. Tools like Semgrep, SonarQube, and CodeQL parse your codebase and build a model of how data flows through it. They flag patterns that match known vulnerability classes.

SAST is good at finding:

  • Hardcoded secrets and credentials left in code
  • SQL injection and command injection patterns
  • Insecure deserialization
  • Use of deprecated or unsafe cryptographic functions
  • Missing input validation on obvious attack surfaces

Because it never executes the application, SAST runs fast. It can be wired into a pre-commit hook or the first stage of a pull request check. The tradeoff is that it cannot see runtime behavior.

A SAST tool has no idea whether an endpoint is actually reachable by an unauthenticated user. It tends to flag things that look dangerous in isolation but are not exploitable in context. That produces false positives, and teams that ignore triage end up ignoring the tool entirely.

What DAST catches

Dynamic Application Security Testing takes the opposite approach. Tools like OWASP ZAP and Burp Suite run against a live, deployed instance of your application. They send real requests and observe real responses, the same way an attacker would.

DAST finds problems that only exist once the app is running:

  • Broken authentication and session management
  • Misconfigured security headers and CORS policies
  • Cross-site scripting that actually executes in a browser
  • Server misconfiguration exposed through live endpoints

DAST is slower than SAST because it has to actually exercise the application. It often crawls every route and form it can find. It also cannot see your source, so it reports symptoms, not the exact line of code causing them. That is a fair trade, since DAST is the only category here that tells you what an attacker outside your codebase can actually reach.

What SCA catches

Software Composition Analysis scans your dependency tree, not your own code. Tools like Snyk and Dependabot check every third-party package and library against databases of known CVEs. They flag which ones you are using and how severe each finding is.

This matters because most modern applications are mostly other people's code. A single npm install can pull in hundreds of transitive dependencies. A critical vulnerability discovered in any one of them becomes your problem the moment it ships.

SCA tools typically also check license compliance, a separate but related risk. Most QA teams do not think about it until legal asks.

package-vulnerability-example.json
{
  "vulnerability": "CVE-2024-XXXX",
  "package": "[email protected]",
  "severity": "high",
  "fixAvailable": "4.17.21",
  "path": ["your-app", "some-middleware", "lodash"]
}

An SCA scan against that dependency tree would flag the outdated lodash version, show the exact path it entered through, and point to the patched release. All of that happens without your team writing a single line of test code.

A worked example: one bug, three tools

Picture a checkout API. SAST flags a raw SQL string built with string concatenation in the discount-code handler, days before it merges. SCA separately flags that the API's JSON parsing library has a known deserialization CVE, patched two minor versions ago. Neither finding alone caused an incident, so the team schedules both fixes for next sprint.

Then a weekly DAST crawl against staging sends a malformed discount code through the live endpoint and gets back a database error with a stack trace in the response body. That confirms the SAST finding was reachable and exploitable, not theoretical. It turns a "schedule for next sprint" ticket into a same-day fix.

This is exactly the coverage gap a test data generator helps close. Realistic and malformed inputs are what surface these paths during DAST runs, similar to how varied load profiles surface performance issues that a single fixed input never would.

When each one runs in the pipeline

The three tools serve different stages because they need different things to exist first:

  • SCA can run the moment a lockfile changes, since it only needs a manifest.
  • SAST needs source code but not a build, so it fits naturally into pull request checks.
  • DAST needs a running deployment, so it belongs later, typically against a staging environment after a successful build and deploy step.

A practical layout: SCA and SAST run on every pull request and block merges on high-severity findings. DAST runs on a schedule against staging, since a full crawl can take longer than a typical PR check allows.

All three should feed the same triage queue. A security finding then gets the same urgency as a failing test in your pipeline, instead of sitting in a separate tool nobody checks. Consistent triage also depends on stable results, which is the same reason flaky tests erode trust in any automated gate.

Why you need all three, not one

A team that picks only one of these tools has a blind spot shaped exactly like the other two. SAST without SCA means you are auditing your own code while ignoring the dependencies that make up most of your application. SCA without DAST means you know your dependencies are patched but have no idea if your authentication flow is actually broken in production. DAST without SAST means you catch exploitable bugs late, after they are already built and deployed.

The three overlap just enough to cover each other's blind spots. Combined, they map onto three questions: is my own code written safely, are the components I depend on safe, and does the running system hold up under attack.

A QA engineer who owns this pipeline should think of the three tools as one system with three inputs, not three separate line items to manage. The same discipline that keeps your API contracts validated applies here: catch the cheap, structural problems early, and reserve the expensive, end-to-end checks for what actually needs them.

FAQ

Questions people ask

Can SAST replace manual code review?

No. SAST catches known patterns reliably but misses logic flaws and business-context issues that require a human reviewer to spot.

How often should DAST scans run?

Most teams run a lightweight DAST scan on every staging deploy and a full authenticated crawl on a weekly schedule, since a complete scan can take hours.

Does SCA catch zero-day vulnerabilities?

No. SCA only flags vulnerabilities that are already published in a CVE database, so it cannot catch an unknown flaw in a dependency before disclosure.

Which tool should a small team adopt first?

SCA is usually the fastest win, since it requires no code changes and immediately surfaces known-vulnerable dependencies you are already shipping.