Safeguard
Tools

Open Source Static Code Analysis Tools

Open source static code analysis tools like Semgrep, CodeQL, and Bandit catch real bugs -- but miss supply-chain flaws like Log4Shell entirely.

Priya Mehta
DevSecOps Engineer
Updated 8 min read

Static code analysis tools scan source code without executing it, flagging bugs, security flaws, and style violations before a single test runs. The open source ecosystem for this category is deep: Semgrep ships with thousands of community rules across 30+ languages, GitHub's CodeQL powers code scanning on public and private repositories alike, and SonarSource's SonarQube Community Edition has been a default CI gate for teams since its first public release in 2008. Security teams often reach for open source static analysis tools first because they're free, run in CI without licensing friction, and catch classic patterns like SQL injection, hardcoded secrets, and unsafe deserialization. But open source SAST tools also have real gaps: they don't tell you which flagged vulnerabilities are actually reachable at runtime, and most stop at your code's boundary -- they don't scan the open source dependencies that make up the majority of a typical application's codebase. This post breaks down the major open source options, what each is actually good at, and where teams end up needing something more.

What Counts as an Open Source Static Code Analysis Tool?

An open source static code analysis tool is source-available software that inspects code -- line by line, via abstract syntax trees, or through control-flow graphs -- to find bugs and vulnerabilities without running the program, and unlike closed commercial platforms, its detection logic is publicly auditable on GitHub or GitLab. This distinguishes it from two adjacent categories teams frequently confuse it with: software composition analysis (SCA), which scans third-party dependency manifests like package-lock.json or pom.xml for known CVEs rather than first-party code, and dynamic analysis (DAST), which tests a running application from the outside. When people search for open source code analysis tools or code static analysis tools, they usually mean this same category -- the naming just varies by who's writing the search query.

The major open source static analysis tools license themselves differently, which matters for enterprise adoption: Semgrep's core engine is LGPL 2.1, CodeQL is free to use on public repositories and under GitHub's own terms for private ones, SonarQube Community Edition is LGPL v3, Bandit and Brakeman are both MIT-licensed, and Flawfinder -- one of the oldest tools in the space, first released by David A. Wheeler in 2001 for C and C++ -- is GPL v2. All of the above qualify as free static analysis tools in the literal sense: no license fee, source available, and no seat-based pricing for the core scanner. Each tool traces back to a specific gap: Bandit came out of the OpenStack Security Project in 2014 because Python lacked a security-focused linter, and Brakeman was built in 2010 specifically because generic linters missed Rails-specific patterns like mass assignment and unsafe render calls.

Which Open Source Tools Should You Actually Use?

For most engineering teams, the practical shortlist comes down to five tools, each dominant in a different niche rather than competing head-to-head. Semgrep is the closest thing to a general-purpose default: it supports 30+ languages with a single YAML-based rule syntax, ships a public registry of community and Semgrep-maintained rules, and added taint-tracking mode in 2021 so rules can follow untrusted input from a source (like an HTTP parameter) to a dangerous sink (like a exec() call) instead of just pattern-matching single lines.

CodeQL, open-sourced by GitHub's Security Lab after the Semmle acquisition in 2019, treats code as a queryable database -- you write queries in QL against a compiled representation of the codebase, which is why it can trace complex dataflow across multiple files and functions. SonarQube Community Edition covers 15+ languages out of the box and is strong on code quality and maintainability debt, though GitHub notes its security-vulnerability rule depth in the free tier is intentionally limited compared to its paid Developer and Enterprise editions. Rounding out the list: Bandit for Python (covering checks like use of eval, pickle, and hardcoded passwords), Brakeman for Ruby on Rails (over 90 distinct check types as of its recent releases), and for Java specifically, SpotBugs with the Find Security Bugs plugin, which adds roughly 140 security-specific bug patterns on top of SpotBugs' general defect detection.

How Do These Tools Actually Catch Vulnerabilities?

They catch vulnerabilities through one of two mechanisms: pattern matching against known-bad code shapes, or dataflow (taint) analysis that traces how untrusted data moves through a program. Pattern matching is fast and low-overhead -- a rule like "flag any call to subprocess.call() where a variable is concatenated into the command string" runs in milliseconds per file and is how tools like Bandit and early Semgrep rules work. Dataflow analysis is slower but far more precise: CodeQL builds a full data-dependency graph for the codebase so it can answer "does data from this HTTP request parameter ever reach this SQL query without sanitization," which is the actual shape of a SQL injection vulnerability rather than just a suspicious-looking string concatenation.

The gap between the two approaches shows up in real incidents. The 2017 Equifax breach traced back to CVE-2017-5638, a vulnerability in the Apache Struts OGNL expression parser -- a flaw that lived inside a third-party library, not in Equifax's own application code, so no amount of first-party static analysis on Equifax's codebase would have surfaced it. That's the core limitation every team running open source SAST needs to internalize early: these tools analyze the code you wrote, not the code you imported.

Can Open Source SAST Catch Supply Chain Vulnerabilities Like Log4Shell?

No -- Log4Shell (CVE-2021-44228), disclosed on December 9, 2021, lived inside the Log4j2 dependency itself, not in any application's own source files, so pure static analysis tools skipped it by design unless a team also ran dependency scanning. The vulnerability -- unauthenticated remote code execution via JNDI lookups in a widely embedded logging library -- affected an enormous swath of the Java ecosystem; Log4j 2.x was estimated to be present, directly or transitively, in hundreds of thousands of software artifacts, and the Apache Software Foundation issued four follow-up CVEs (including CVE-2021-45046 and CVE-2021-45105) within three weeks as the initial patch proved incomplete.

Catching this class of vulnerability requires a dependency graph, not a code scanner. Open source options here include OWASP Dependency-Check (in active development since 2012, matching dependencies against the NVD feed) and Trivy from Aqua Security, which scans both dependency manifests and container images. The practical lesson for any team relying solely on Semgrep, CodeQL, or SonarQube: a clean SAST scan tells you nothing about whether you're shipping a vulnerable version of Log4j, Spring, or OpenSSL, because none of those tools were built to inspect the transitive dependency tree.

What Are the Practical Limitations of Open Source Static Analysis Tools?

The three limitations that show up most consistently in production use are false-positive volume, no runtime reachability signal, and tool fragmentation. On false positives: because most rules match on code shape rather than actual exploitability, a single Semgrep or SonarQube ruleset run against a large monorepo commonly surfaces findings numbering in the hundreds to low thousands, and security teams report triage backlogs where a large share of flagged issues are either dead code, test fixtures, or patterns that are technically matched but never executed with attacker-controlled input.

On reachability: none of these tools by default know whether the function containing a flagged vulnerability is ever called from an entry point reachable by an external user, which means a "critical" finding in an unused internal utility function gets the same severity label as one in a public API handler. On fragmentation: a polyglot codebase running Python, Java, Ruby, and Terraform typically needs four or five separate open source tools stitched together -- Bandit, SpotBugs, Brakeman, Checkov -- each with its own config format, suppression syntax, and CI integration, and no shared view of which findings across all of them actually matter most.

How Do You Choose Between Open Source and Commercial SAST?

Choose static code analysis open source tools for language-specific spot checks and free CI gates on individual repositories, and layer in a commercial or enterprise platform once you need cross-repo prioritization, reachability context, and audit-ready reporting at organizational scale. A five-person team maintaining two Python services can run Bandit and Semgrep's free registry rules directly in GitHub Actions and get real coverage at zero licensing cost. A 200-engineer organization running 400 repositories across six languages faces a different problem: not "can we detect issues" but "which of the 3,000 detected issues across all those tools should the three people on the security team fix this week," and that triage problem is exactly what open source SAST tools, built to analyze one codebase at a time, aren't designed to solve.

How Safeguard Helps

Safeguard sits on top of the open source and commercial scanners teams already run rather than asking them to rip anything out, and focuses specifically on the triage problem those tools leave unsolved. Its reachability analysis traces whether a flagged function in a Semgrep, CodeQL, or dependency-scan finding is actually invoked from code your application calls in production, cutting through the false-positive volume described above so teams fix the handful of findings that matter instead of the hundreds that don't. Griffin AI, Safeguard's analysis engine, correlates those reachability signals with exploitability data and generates auto-fix pull requests for common vulnerability classes, turning a flagged finding directly into a reviewable code change instead of a ticket. Safeguard also generates and ingests SBOMs across your repositories, giving you the dependency-level visibility that pure static analysis tools -- as the Log4Shell example above illustrates -- were never built to provide on their own.

Never miss an update

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