Skip to main content

Blog / AppSec basics

SAST vs SCA: what each one finds, and why you need both

SAST and SCA are the two scans almost every security programme starts with, and they are easy to confuse. One reads your code, the other reads your dependencies. Here is what each finds, with examples, and how to run them together without drowning in findings.

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 vs SCA at a glance
SASTSCA
Looks atYour source codeDependency manifests and lockfiles (and the packages they resolve to)
FindsInsecure patterns in your code: injection, XSS, path traversal, unsafe deserialisation, weak cryptoKnown vulnerabilities (CVEs) in open-source packages, license risks, malicious or suspicious packages
IdentifiersCWE (the weakness type)CVE and advisory IDs (the specific vulnerability)
Typical fixChange your codeUpgrade, replace or remove a package
False positives come fromFlagged patterns that untrusted input never reachesVulnerable functions your code never calls
Blind spotsVulnerabilities inside dependencies; runtime configurationFlaws in your own code; zero-days not yet in advisory data
Output for othersFindings and reportsFindings, 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.

A SAST finding: request input concatenated into SQL (CWE-89)
String id = request.getParameter("id");                          // source: attacker-controlled
String query = "SELECT * FROM orders WHERE id = " + id;
ResultSet rs = conn.createStatement().executeQuery(query);       // sink: SQL injection
The fix SAST points you to: a parameterised query
PreparedStatement 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.

An SCA finding: a dependency with a known, actively exploited vulnerability
<!-- 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

  1. Known exploitation. Is the vulnerability in the CISA KEV catalog (opens in a new tab)? If so, attackers are already using it.
  2. Exploit probability. The Exploit Prediction Scoring System (EPSS) estimates the probability of exploitation in the next 30 days.
  3. Reachability. Does your code call the vulnerable function, or is the package only present? Treat missing evidence as unknown, not as safe.
  4. 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

  1. Findings where a data-flow trace shows attacker-controlled input reaching the sink.
  2. Findings in code that is exposed: public routes, authentication, payment and file handling.
  3. 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?.

Which scan finds what
ProblemFound by
SQL injection in your controllerSAST
A vulnerable version of a logging or parsing librarySCA
A GPL package in a proprietary productSCA (license)
An API key committed last month and later deletedSecret detection (git history)
A storage bucket open to the internet in TerraformIaC scanning
A vulnerable OpenSSL in your base imageContainer scanning
A missing ownership check on an endpointCode 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.

Your next step

Run SAST and SCA on one of your repositories.

Connect a repository on the Free plan and see code and dependency findings, prioritised by exploit signal, in one scan.

Get started free