Safeguard
Security

What a Static Application Security Test Catches (and What It Misses)

A clear-eyed look at the static application security test: how SAST works, the vulnerability classes it finds, its blind spots and false positives, and how to run it without drowning developers.

Yukti Singhal
Security Analyst
6 min read

A static application security test (SAST) analyzes an application's source code, bytecode, or binaries without running the program, looking for patterns that indicate security vulnerabilities like injection, hardcoded secrets, and unsafe data flows. It is the "white-box" half of application security testing — it reads the code the way a very literal, very fast reviewer would. Used well, a static application security test catches whole classes of bugs before they ever reach a running environment. Used badly, it buries developers in false positives until they stop reading its output. This guide covers both the value and the limits.

How a static application security test works

SAST tools parse your code into a model — typically an abstract syntax tree, then a control-flow and data-flow graph — and run rules against that model. The most valuable analysis is taint tracking: the tool marks data entering from an untrusted source (an HTTP parameter, a file, a message queue) as "tainted" and follows it through the code. If tainted data reaches a dangerous "sink" (a SQL query, a shell command, an HTML response) without passing through a recognized sanitizer, the tool reports a potential vulnerability.

Because it works on the code itself, SAST runs early — you can wire it into a pre-commit hook, a pull-request check, or a CI pipeline, long before there is a deployed application to attack. That "shift left" property is its main advantage: the earlier a flaw is caught, the cheaper it is to fix.

What it catches well

A static application security test is strong on vulnerability classes that show up as recognizable code patterns:

  • Injection flaws — SQL, OS command, LDAP — where untrusted input flows into a query or command. Rather than a working exploit, think of the pattern SAST flags: input concatenated directly into a query string, e.g. "SELECT * FROM users WHERE id = " + userInput, with no parameterization in between. The fix it points you toward is parameterized queries.
  • Cross-site scripting (XSS) where user input reaches an HTML sink without encoding.
  • Hardcoded secrets — API keys, passwords, and tokens committed into source.
  • Insecure cryptography — use of broken algorithms like MD5 for passwords, or predictable random number generators for security tokens.
  • Path traversal and unsafe deserialization patterns.
  • Misuse of security APIs — disabled TLS verification, permissive CORS, weak cookie flags.

These are exactly the categories that dominate the OWASP Top 10, which is part of why an application security test program almost always starts with SAST.

Where it is blind

Being honest about the blind spots is what separates a useful program from a checkbox one.

  • Runtime and configuration issues. SAST does not see how the app is deployed, what environment variables are set, or how the load balancer is configured. A misconfigured server is invisible to it. That is DAST's job.
  • Business-logic flaws. A static application security test does not understand your domain. It cannot tell that a user is able to approve their own expense report, or that a price can be set to a negative number. These are design problems no pattern-matcher catches.
  • Broken authorization. Whether a given user should be allowed to reach a given resource is context the tool lacks.
  • Vulnerabilities in third-party dependencies. SAST analyzes your code; known CVEs in the libraries you import are the domain of software composition analysis. Most tool suites run SCA alongside SAST for exactly this reason.

A static test that finds zero business-logic bugs is not doing badly — it was never able to find them. Set expectations accordingly.

The false-positive problem

The single biggest complaint about SAST is noise. Because the tool reasons about code paths conservatively, it flags things that are technically reachable but practically safe — input that is validated in a way the tool does not recognize, or a "sink" that is only ever fed constants. High false-positive rates are corrosive: once developers learn that most alerts are noise, they stop reading any of them, and the real finding hidden in the pile ships anyway.

Managing this is a program problem, not just a tool setting:

  • Tune the ruleset to your stack instead of running everything at maximum sensitivity on day one.
  • Baseline existing findings so the pipeline gates only on new issues introduced by a change, rather than failing every build on a decade of legacy debt.
  • Suppress with a reason. When you mark a finding as a false positive, record why, so the decision is auditable and not just a silent dismissal.
  • Route findings to the code owner in the pull request, with the offending line and a fix suggestion, not into a separate dashboard nobody opens.

Running it well in CI/CD

The goal is a static application security test that developers experience as a fast, specific guardrail. Practical setup:

  • Run it on pull requests, scoped to the diff where possible, so feedback arrives in minutes.
  • Fail the build only on new, high-confidence, high-severity findings; report the rest without blocking.
  • Give developers the finding where they already work — in the PR, with a clear explanation and remediation guidance.
  • Feed results into your broader application security risk management process so SAST output is prioritized against everything else rather than treated as its own island.

SAST is necessary, not sufficient

A static application security test is one instrument in the application security test suite, not the whole orchestra. It excels at finding code-pattern vulnerabilities early and cheaply, and it is genuinely worth running on every change. But it is blind to runtime behavior, configuration, business logic, and dependency CVEs. Pair it with DAST for runtime coverage, SCA for dependency risk, and human review or threat modeling for design flaws. Any vendor pitching SAST as complete application security is selling you a corner of the picture as though it were the frame.

FAQ

What is the difference between SAST and DAST?

SAST (static) analyzes code without running it and catches code-pattern flaws like injection and hardcoded secrets early. DAST (dynamic) tests a running application from the outside and catches runtime and configuration issues SAST cannot see. They are complementary; mature programs run both.

Why does my SAST tool report so many false positives?

Static analysis reasons about code paths conservatively, so it flags issues that are technically reachable but practically safe. Tune the ruleset to your stack, baseline old findings so you gate only on new ones, and suppress false positives with a documented reason to keep the signal usable.

Can a static application security test find vulnerabilities in my dependencies?

No. SAST analyzes your own source code. Known vulnerabilities in third-party libraries are found by software composition analysis (SCA), which most teams run alongside SAST.

When should SAST run in the development pipeline?

As early as practical — ideally on pull requests, scoped to the changed code so feedback returns in minutes. Fail builds only on new, high-confidence, high-severity findings to avoid blocking on legacy debt, and surface results directly in the PR.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.