SAST and SCA
Modern application security testing pushes vulnerability detection as early into the development lifecycle as possible โ "shift left." Two of the foundational static techniques for doing this are SAST (Static Application Security Testing), which analyses the code your organisation actually writes, and SCA (Software Composition Analysis), which analyses the third-party and open-source components your code depends on. They answer different questions and neither substitutes for the other: SAST finds vulnerabilities you introduced; SCA finds vulnerabilities you imported. In a typical modern codebase where third-party and open-source dependencies make up the majority of the shipped code, skipping either leaves a large, predictable gap.
This article covers what each technique does, what it does and doesn't catch, how to roll both out without drowning development teams in noise, and how they map to NIST SP 800-218 (SSDF) and OWASP guidance.
SAST, SCA, and Where DAST Fits
| Technique | Analyses | When | Finds | Blind Spot |
|---|---|---|---|---|
| SAST | Your own source code, bytecode, or binaries โ without executing the application | Earliest โ IDE, pre-commit, CI build | Coding-level vulnerabilities: injection flaws, hardcoded secrets, insecure crypto usage, unsafe deserialization | Business logic flaws, runtime/environment-dependent issues, anything in a dependency it has no rules for |
| SCA | The inventory of third-party and open-source components your code pulls in, direct and transitive | Alongside SAST โ build time, and continuously post-release as new CVEs are published | Known CVEs in dependencies, outdated/unmaintained packages, license compliance risk, malicious/typosquatted packages | Vulnerabilities in your own first-party code; a listed CVE that isn't actually reachable by your code |
| DAST (out of scope here) | The running application from the outside, black-box, over HTTP | Later โ staging/pre-production | Runtime and configuration issues, auth/session flaws, issues that only manifest when the app is actually executing | Requires a running, reasonably complete environment; slower; can't point to a specific line of source |
SAST and SCA are complementary, not competing โ most mature AppSec programs run both on every build. DAST is a separate, later-stage technique and isn't covered in depth here.
SAST โ Static Application Security Testing
How It Works
SAST tools parse source code (or bytecode/binaries when source isn't available) into an abstract syntax tree and build control-flow and data-flow graphs from it โ all without ever running the application. The core technique most SAST tools rely on is taint analysis: tracking untrusted input from a source (a request parameter, a file read, an environment variable) through the code to a sink (a SQL query, a shell command, a file path, an HTML response) and flagging any path where the data reaches a dangerous sink without passing through recognised sanitisation.
What SAST Finds
| Vulnerability Class | Example Pattern | Related OWASP Category |
|---|---|---|
| SQL injection | User input concatenated directly into a query string | A03:2021 โ Injection |
| Command injection | User input passed to a shell/exec call | A03:2021 โ Injection |
| Cross-site scripting (XSS) | Untrusted input written to an HTML response without encoding | A03:2021 โ Injection |
| Path traversal | User-controlled input used to construct a filesystem path | A01:2021 โ Broken Access Control |
| Hardcoded secrets | API keys, passwords, or private keys committed directly in source | A02:2021 โ Cryptographic Failures |
| Weak/incorrect cryptography | Use of deprecated algorithms (MD5/SHA-1 for passwords, ECB mode) | A02:2021 โ Cryptographic Failures |
| Insecure deserialization | Deserializing untrusted data without type/allowlist restrictions | A08:2021 โ Software and Data Integrity Failures |
| SSRF-prone request construction | User-controlled input used to build an outbound request URL | A10:2021 โ Server-Side Request Forgery |
Limitations
- False-positive rate. Untuned SAST is notorious for flagging code that's already safely sanitised through a pattern the tool doesn't recognise โ this is the single biggest reason SAST rollouts fail: developers stop trusting a noisy tool and start ignoring it entirely.
- No business logic or access-control awareness. A SAST tool can't tell you that a user can view another user's order by changing an ID in the URL โ that requires runtime context it doesn't have (see API Security on broken object-level authorisation).
- Framework and dynamic-code blind spots. Heavy use of reflection, dependency injection containers, or dynamically constructed code can break the data-flow tracing SAST relies on.
- Doesn't cover dependency code. A SAST tool generally won't deeply analyse the internals of a third-party library it doesn't have rules for โ that gap is exactly what SCA exists to close.
Rollout
Run SAST in three phases, the same audit-then-enforce pattern used elsewhere in secure deployment (see Web Application Firewall and Application Control for the same principle applied to other controls):
- Baseline. Scan the existing codebase without blocking anything. Catalogue existing findings as tracked technical debt โ don't try to fix it all before turning the tool on for new code.
- Gate new code only. Configure the CI pipeline to fail only on new findings introduced by a pull request's diff, not on pre-existing findings in files the PR didn't touch. This is the single most important rollout decision โ gating on the full existing findings count guarantees the pipeline is red on day one and gets bypassed or disabled out of frustration.
- Expand and tighten. As legacy debt is worked down and false-positive rules are tuned, progressively lower the severity threshold that blocks a merge, and extend coverage to more of the codebase (test code, IaC templates, etc.).
Layer feedback as early as the workflow allows: IDE plugin (fastest feedback, before commit) โ pre-commit hook for the highest-confidence rules only โ full CI scan on every PR โ scheduled full-codebase scan to catch anything a diff-based scan missed (e.g. a new sink introduced far from the actual tainted source).
# Illustrative CI step โ tool-agnostic pattern
sast_scan:
script:
- sast-tool scan --diff-only --baseline main --fail-on=critical,high
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
SCA โ Software Composition Analysis
How It Works
SCA tools build a full dependency tree โ direct dependencies your code explicitly imports, and every transitive dependency those pull in โ and match each component and version against vulnerability databases (the NVD/CVE database, the GitHub Advisory Database, OSV, and vendor-specific feeds). Mature SCA tools go further with reachability analysis: using the call graph to determine whether your code actually calls the vulnerable function in a dependency, rather than flagging every CVE in every package regardless of whether the vulnerable code path is ever exercised.
What SCA Finds
- Known CVEs in direct and transitive dependencies
- Outdated dependencies with no available patched version (an end-of-life exposure that a CVE match alone won't surface)
- License compliance risk โ copyleft licenses (GPL, AGPL) pulled into proprietary codebases without the organisation's awareness
- Malicious or typosquatted packages โ an increasingly common supply-chain attack vector where a package name is deliberately similar to a popular one
- Unmaintained/abandoned packages โ no updates in years, a single maintainer, or other supply-chain risk signals independent of any specific known CVE
Limitations
- Database lag. A vulnerability that hasn't been publicly disclosed or catalogued yet won't be flagged โ SCA is only as current as the feeds it consumes.
- Reachability gaps in less mature tools. Basic SCA tools flag every CVE match regardless of whether your code path ever calls the vulnerable function, generating significant noise; this is a meaningful maturity differentiator between tools.
- Monorepo/vendored code confusion. Forked or vendored copies of a library can confuse version-string matching, producing both false positives and false negatives.
- Doesn't cover your own code. That's SAST's job.
Software Bill of Materials (SBOM)
An SBOM is a formal, machine-readable inventory of every component in a piece of software and how they relate to each other. In the US, Executive Order 14028 (Section 10(j)) directed NTIA to define the SBOM baseline, resulting in the 2021 NTIA Minimum Elements for an SBOM; CISA published updated guidance in 2025 expanding the required metadata for provenance and authenticity. The two dominant machine-readable formats are:
| Format | Origin | Notes |
|---|---|---|
| SPDX | Linux Foundation | Broader scope (licensing, provenance); an ISO/IEC standard |
| CycloneDX | OWASP | Originally security-focused; strong native support for vulnerability and dependency-graph data |
Generating an SBOM as a build artefact (most SCA tools do this natively) gives you a durable, shareable record of exactly what shipped in a given release โ valuable both for your own incident response when a new CVE drops and for downstream customers who increasingly require one contractually.
Rollout
The same phased approach as SAST applies:
- Inventory first. Run SCA across the existing codebase in informational mode and get a full picture of what's actually in use before blocking anything.
- Gate new/changed dependencies. Fail the build when a PR adds or upgrades to a dependency with a critical/high severity CVE that has an available fix โ this is a much smaller, more tractable gate than "the whole dependency tree must be clean."
- Expand scope over time. Extend gating to transitive dependencies, lower severities, and license-policy violations as the existing debt is triaged and either remediated or explicitly accepted.
Pair this with automated dependency-update tooling (Dependabot/Renovate-style bots are the common pattern) so that patched versions get proposed automatically rather than relying on someone to notice a new CVE manually.
# Illustrative CI step โ tool-agnostic pattern
sca_scan:
script:
- sca-tool scan --fail-on=critical,high --only-with-fix-available
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
Alignment with NIST SP 800-218 (SSDF) and OWASP
NIST SP 800-218, the Secure Software Development Framework, maps cleanly onto both techniques:
| SSDF Practice | Description | Maps To |
|---|---|---|
| PW.7 | Review and/or analyse human-readable code to identify vulnerabilities and verify compliance with security requirements | SAST |
| PW.4 | Reuse existing, well-secured software instead of duplicating functionality โ includes vetting third-party components before use | SCA |
| RV.1 | Identify and confirm vulnerabilities on an ongoing basis | SCA's continuous CVE monitoring, post-release |
For OWASP alignment: SAST findings map across several OWASP Top 10 categories (most commonly A03 Injection, A02 Cryptographic Failures, A08 Software and Data Integrity Failures โ see the table above). SCA maps most directly to A06:2021 โ Vulnerable and Outdated Components, and its CI/CD integration practices are also covered by the OWASP Top 10 CI/CD Security Risks project.
Rollout Checklist
| Control | Priority | Notes |
|---|---|---|
| SAST and SCA both run on every build โ neither substitutes for the other | Critical | They cover disjoint vulnerability classes |
| CI gating is diff/new-code-aware, not blocking on pre-existing findings | Critical | The single biggest driver of whether a rollout succeeds or gets disabled in frustration |
| Baseline/inventory phase run before any blocking gate is enabled | High | Prevents the pipeline going red on day one |
| SAST feedback available in the IDE and/or pre-commit, not only in CI | Medium | Faster feedback loop, cheaper fix earlier |
| SCA gating scoped initially to critical/high severity with an available fix | High | A much more tractable initial gate than the full dependency tree |
| Reachability analysis used (or planned) to reduce SCA false positives | Medium | Meaningful maturity differentiator between tools |
| SBOM generated as a build artefact (SPDX or CycloneDX) | Medium | Required increasingly by contract; essential for fast incident response when a new CVE drops |
| License policy defined and enforced via SCA | Medium | Prevents unintentional copyleft-license exposure in proprietary code |
| Automated dependency-update tooling in place | Medium | Reduces reliance on manual CVE monitoring |
| Severity thresholds and scope tightened progressively as debt is worked down | Medium | Matches the audit-then-enforce pattern used for other controls in this wiki |