Key takeaways
- SAST (static application security testing) reads the code your team writes and looks for insecure patterns such as injection, unsafe file handling and weak cryptography.
- SCA (software composition analysis) reads your dependency manifests and lockfiles and looks for open-source packages with known vulnerabilities and license issues.
- They answer different questions, so neither replaces the other. Most of the code in a typical application comes from dependencies, and most of the logic attackers target is your own.
- Prioritise SCA findings by exploit signal (known exploitation, then exploit probability, then reachability) and SAST findings by confidence and whether untrusted input reaches the flaw.
- Run both on every pull request, gate on new findings, and add secret, IaC and container scanning to cover what neither sees.
The short answer
SAST analyses your source code without running it, to find security flaws in the code you wrote. SCA inventories the third-party packages your code depends on, directly and transitively, and checks them against vulnerability and license data. SAST finds the SQL injection in your controller; SCA finds the vulnerable version of the logging library under it.
| SAST | SCA | |
|---|---|---|
| Looks at | Your source code | Dependency manifests and lockfiles (and the packages they resolve to) |
| Finds | Insecure patterns in your code: injection, XSS, path traversal, unsafe deserialisation, weak crypto | Known vulnerabilities (CVEs) in open-source packages, license risks, malicious or suspicious packages |
| Identifiers | CWE (the weakness type) | CVE and advisory IDs (the specific vulnerability) |
| Typical fix | Change your code | Upgrade, replace or remove a package |
| False positives come from | Flagged patterns that untrusted input never reaches | Vulnerable functions your code never calls |
| Blind spots | Vulnerabilities inside dependencies; runtime configuration | Flaws in your own code; zero-days not yet in advisory data |
| Output for others | Findings and reports | Findings, plus an SBOM you can share |
What SAST is and how it works
Static application security testing parses your code into a structure it can reason about, then applies rules. Simple rules match a dangerous call. Better rules follow data flow: they trace a value from a source an attacker controls (a request parameter, a header, a file) to a sink where it causes harm (a SQL query, a shell, an HTML response), and check whether anything sanitises it on the way.
String id = request.getParameter("id"); // source: attacker-controlled
String query = "SELECT * FROM orders WHERE id = " + id;
ResultSet rs = conn.createStatement().executeQuery(query); // sink: SQL injectionPreparedStatement stmt = conn.prepareStatement("SELECT * FROM orders WHERE id = ?");
stmt.setLong(1, Long.parseLong(request.getParameter("id")));
ResultSet rs = stmt.executeQuery();SAST is good at the bug classes that have a recognisable shape: injection of every kind, cross-site scripting, path traversal, server-side request forgery, insecure deserialisation, weak hashing and encryption, and dangerous APIs. It runs early, on every change, with no running environment.
Its limits are worth knowing:
- It does not understand your business rules. A missing ownership check ("can this user see this invoice?") is usually invisible to it.
- It produces false positives when it cannot prove that input is sanitised or never attacker-controlled. Tune rules and use confidence to triage.
- It does not see runtime configuration, deployed infrastructure or the vulnerabilities inside your dependencies.
- Depth varies by language and framework. Evaluate a tool on representative code from your own stack.
What SCA is and how it works
Software composition analysis starts with an inventory. It reads manifests and lockfiles (package-lock.json, poetry.lock, pom.xml, go.sum and so on), resolves the full tree of direct and transitive dependencies, and matches each package version against vulnerability advisories. Most of the packages in a typical tree are transitive: you never chose them, but you ship them.
<!-- pom.xml -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version> <!-- CVE-2021-44228 (Log4Shell): remote code execution -->
</dependency>Log4Shell is the textbook case. The flaw was not in anyone's application code, so SAST on that code would never find it. It was in a ubiquitous logging library, often pulled in transitively, and it is listed in CISA's Known Exploited Vulnerabilities catalog. SCA flags it from the version number alone; the fix is to upgrade to a patched release (2.17.1 or later for the follow-up issues).
Beyond vulnerabilities, SCA typically covers:
- Licenses, so a copyleft or unknown license does not reach a product that cannot accept it.
- Malicious and suspicious packages, such as known malware advisories and typosquatted names.
- An SBOM (software bill of materials) in CycloneDX or SPDX format, which customers and regulators increasingly ask for.
- Outdated packages that are not vulnerable yet but are falling behind.
SCA's limits mirror SAST's. It knows nothing about your own code's flaws, it can only report vulnerabilities that are in advisory data, and a vulnerable package is not always an exploitable one: your code may never call the affected function.
How to prioritise findings from each
Both scans can produce long lists. Prioritise with evidence rather than severity labels alone.
SCA: exploit signal first
- Known exploitation. Is the vulnerability in the CISA KEV catalog (opens in a new tab)? If so, attackers are already using it.
- Exploit probability. The Exploit Prediction Scoring System (EPSS) estimates the probability of exploitation in the next 30 days.
- Reachability. Does your code call the vulnerable function, or is the package only present? Treat missing evidence as unknown, not as safe.
- Severity. CVSS describes how bad exploitation would be. It is the tie-breaker, not the starting point: a critical CVE in an unreachable development dependency outranks very little.
SAST: confidence and reachable input
- Findings where a data-flow trace shows attacker-controlled input reaching the sink.
- Findings in code that is exposed: public routes, authentication, payment and file handling.
- Pattern-only findings, triaged for false positives, with a recorded reason when dismissed.
Running SAST and SCA together
The practical setup is the same for both:
- Scan every pull request, so findings arrive while the author still has context.
- Gate on new findings, not the backlog. Block a merge that introduces a high-confidence SAST issue or a new KEV-listed dependency; fix the existing backlog on a schedule.
- Scan the default branch on a schedule as well. SCA results change when new advisories are published, even if your code does not.
- Record decisions. False positives and accepted risks need a reason and, for accepted risks, an expiry.
Neither scan covers everything. Most programmes add secret detection (keys and tokens in code and git history), infrastructure-as-code scanning (Terraform, Kubernetes, Dockerfiles), container image scanning (OS packages in base images) and, at runtime, DAST (dynamic testing of the running application). If your application calls AI models or agents, add an inventory of those too; see What is an AI-BOM?.
| Problem | Found by |
|---|---|
| SQL injection in your controller | SAST |
| A vulnerable version of a logging or parsing library | SCA |
| A GPL package in a proprietary product | SCA (license) |
| An API key committed last month and later deleted | Secret detection (git history) |
| A storage bucket open to the internet in Terraform | IaC scanning |
| A vulnerable OpenSSL in your base image | Container scanning |
| A missing ownership check on an endpoint | Code review and tests (rarely any scanner) |
Choosing SAST and SCA tools
Evaluate on your own repositories, not on a vendor's demo project. For each candidate, run the same representative repositories and compare: confirmed findings, false positives, issues you know about that it missed, how clearly each finding shows its evidence, and how much work it takes to act on the results. Check language and ecosystem coverage against what you actually ship, and whether results arrive in the pull request where developers will see them.
CodeStax runs SAST and SCA in the same scan, alongside secret detection, IaC, container and AI attack-surface analysis, for GitHub, GitLab and Bitbucket repositories. SAST findings map to CWE across documented languages including Python, JavaScript, TypeScript, Java, Go, Ruby, PHP, C#, Kotlin, Swift and Rust. SCA covers npm, pip, Maven, Gradle, Go modules, Cargo, Composer, RubyGems and NuGet, prioritises by KEV and EPSS alongside CVSS, and exports SBOMs in CycloneDX or SPDX.
Common questions
What is the difference between SAST and SCA?
SAST analyses the source code your team writes for insecure patterns such as injection. SCA analyses the open-source dependencies your code uses for known vulnerabilities, license issues and malicious packages. SAST reports weaknesses (CWE); SCA reports specific vulnerabilities (CVE).
Do I need both SAST and SCA?
Yes, if you write code and use open-source packages, which almost everyone does. They find different problems: SAST cannot see vulnerabilities inside a library, and SCA cannot see flaws in your own code.
What is the difference between SAST and DAST?
SAST reads source code without running it. DAST (dynamic application security testing) attacks a running application from the outside. SAST finds issues early and points to the line; DAST finds issues that only appear at runtime, such as misconfiguration. They complement each other.
Which should I start with, SAST or SCA?
Many teams start with SCA because it is fast to set up, has few false positives and catches widely exploited issues such as Log4Shell. Add SAST soon after, gated on new findings in pull requests so the backlog does not block delivery.
Is an SBOM the same as SCA?
No. An SBOM is an inventory of components. SCA produces that inventory and also matches it against vulnerability and license data. An SBOM alone tells you what you ship, not what to fix.