Skip to content

Bandit vs Semgrep

Suphi Cankurt

Written by Suphi Cankurt

Bandit vs Semgrep
Key Takeaways
  • Bandit is Python-only. Semgrep covers 30+ languages including Python, JavaScript, TypeScript, Java, Go, Ruby, C, C++, C#, Kotlin, and Swift.
  • Both are open source. Bandit ships under Apache 2.0, the Semgrep CE engine under LGPL-2.1 (with the Opengrep community fork on the same license). Semgrep AppSec Platform layers managed rules and a SaaS dashboard on top with paid tiers.
  • Bandit's ruleset is small and Python-specific (about 90 plugins covering common Python crypto, deserialization, and shell-injection risks). Semgrep's public rules registry has thousands of community-maintained rules across all supported languages.
  • Semgrep wins on custom rules. You write Semgrep rules in YAML using a Python-like pattern syntax. Bandit custom rules require writing a Python plugin against its AST API, which is much more work.
  • Most teams converge on Semgrep for polyglot stacks and custom-rule needs. Bandit stays useful as a Python-specialised second opinion, with rules curated by Python security researchers since 2014.

Which Is Better: Bandit or Semgrep?

Bandit vs Semgrep in one line: Bandit is a Python-only AST scanner with around 90 curated plugins under Apache 2.0. Semgrep is a polyglot rules engine covering 30+ languages with thousands of YAML-defined rules under LGPL-2.1.

Choose Bandit when the project is pure Python and you want zero-config, drop-in scanning with a Python-specialised ruleset.

Choose Semgrep when the codebase is polyglot, you need custom rules, or you want IDE-time feedback and a SaaS triage dashboard.

For polyglot codebases, Semgrep is the practical pick. One engine handles 30+ languages, thousands of community rules, and YAML-based custom rules anyone on the team can write.

Side-by-side comparison card: multi-language SAST (Semgrep, 30+ languages, generic patterns) versus Bandit (Python-only, AST-based scanner with curated PyCQA plugin ruleset) Bandit is built only for Python; Semgrep covers 30+ languages with adapted generic patterns.

For pure Python projects, the case for Bandit holds up. Its Python ruleset has been curated by Python security researchers since 2014, and pip install bandit && bandit -r src/ is the lowest-friction Python SAST in the OSS world.

Most teams that start with Bandit add Semgrep as the second engine when they outgrow Python-only or need custom rules. Semgrep then often becomes the primary engine and Bandit stays as a Python-specialised second opinion.

Key Differences

DimensionBanditSemgrep
Language coveragePython only30+ languages
LicenseApache 2.0LGPL-2.1 engine (Opengrep fork same license) + paid AppSec Platform
Rule count~90 pluginsThousands across all languages in public registry
Custom rulesPython plugin against Bandit AST APIYAML pattern syntax, easy to author
CI integrationCLI, pre-commit, GitHub ActionsCLI, pre-commit, CI integrations + SaaS dashboard
IDE pluginsNone first-partyVS Code, JetBrains, Vim, Emacs
Best forPure Python projects, drop-in scannerPolyglot stacks, custom rules, security guardrails

Head-to-Head

Language coverage

Bandit is Python-only. The scanner reads Python source code, parses it into an AST, and runs around 90 plugins that look for Python-specific risk patterns.

Bandit terminal output scanning examples/yaml_load.py: B506 yaml_load issue, severity Medium, confidence High, with code excerpt and run metrics A real bandit run flagging an unsafe yaml.load call with location, severity, and a docs link.

Semgrep covers 30+ languages: Python, JavaScript, TypeScript, Java, Go, Ruby, C, C++, C#, Kotlin, Swift, PHP, Scala, Rust, Bash, Terraform, Dockerfile, and more.

Semgrep CLI output running semgrep –config=auto across 847 files in 10 seconds, finding 12 issues across Python and JavaScript with rule names like dangerous-yaml-load and tainted-sql-query semgrep --config=auto runs the same project through 3,247 rules across multiple languages in one pass.

For a Python-only project, both work. For anything else, Semgrep is the only one of the two that helps.

Rule philosophy

Bandit ships a curated, Python-specific set of around 90 plugin rules. They cover classic Python AppSec risks: hardcoded credentials, weak crypto (insecure hashlib usage), Pickle deserialization, shell injection via subprocess, SQL injection, SSL verification disabled, debug mode in Flask / Django, and so on.

Bandit project page on PyPI showing version 1.9.4, Apache 2.0 license, supported Python versions 3.10 through 3.14, and links to PyCQA source repo Bandit on PyPI: maintained by PyCQA, Apache 2.0, installable via pip install bandit.

Semgrep is rules-based pattern matching on the abstract syntax tree. Rules are written in YAML using a Python-like pattern syntax. The public registry at semgrep.dev/r hosts thousands of community-maintained rules across all supported languages.

Semgrep annotated taint flow showing user input entering through request.form, flowing through json.dumps and a Jinja2 template variable, with rule matches highlighted in a VS Code-style code view Semgrep tracks how user input flows through the code, matching rules against the resolved data path.

Bandit’s Python ruleset is dense and tuned. Semgrep’s Python ruleset is broader because it includes generic SAST patterns alongside Python-specific rules.

Writing custom rules

Bandit custom rules require writing a Python plugin module that registers itself with Bandit’s plugin manager and walks the AST using Bandit’s API. It is closer to writing a small Python linter than a config snippet.

PyCQA/bandit GitHub repository file tree with directories for bandit, doc, examples, tests, and configuration files such as pre-commit hooks and tox config The PyCQA/bandit repo: plugins live in the bandit/ directory; new rules are Python modules in that tree.

Semgrep custom rules are YAML: a pattern, a message, a severity, and optional metadata. Most security engineers can write a useful Semgrep rule in 10 minutes.

Semgrep playground rule editor showing YAML rule with id, pattern print(…), message, languages: [python], and severity WARNING, alongside test code with print() matches highlighted The Semgrep playground at semgrep.dev/playground: a working rule is six YAML lines.

If your team expects to write custom rules regularly (enforcing architectural patterns, banning dangerous APIs, codifying security learnings) Semgrep is much less friction.

CI and developer experience

Both tools work as CLI, pre-commit hook, and CI step. Bandit is dead simple to drop in: pip install bandit && bandit -r src/. Semgrep has the same pattern: pip install semgrep && semgrep ci.

Semgrep adds a SaaS dashboard via the AppSec Platform. It is useful for teams that want triage workflows, central exclusion management, and reporting across many repos. Bandit’s reporting story is CLI output and JSON / SARIF files; integration with downstream tools is on you.

For IDE integration, Semgrep ships first-party plugins for VS Code and JetBrains. Bandit relies on third-party IDE wrappers.

Performance

Both are fast on Python codebases. Bandit’s narrow scope (~90 plugins, Python AST) keeps it lean. Semgrep’s general engine adds some overhead per file but scales well to large polyglot repos with rule-set tuning.

For a 100kLOC Python project, both scanners typically complete in seconds to minutes, well within CI budgets.

When to Choose Each

Decision tree titled ‘Bandit or Semgrep: how to choose’ branching on Python-only codebase yes-no, then on custom-rule and IDE-feedback needs, ending at Semgrep, Bandit, or Semgrep-plus-Bandit Three questions decide it: language reach first, then custom rules and IDE plugins.

Choose Bandit when

  • The project is pure Python and you want a focused Python SAST.
  • You want zero-config, drop-in scanning with no SaaS dashboard.
  • The team trusts a curated, Python-specialised ruleset.

Choose Semgrep when

  • The codebase is polyglot (Python plus JS/TS, Java, Go, etc.).
  • You expect to write custom rules to enforce internal patterns.
  • IDE-time feedback for developers is part of the requirement.
  • You want a SaaS dashboard for centralised triage and reporting.

Choose both when

  • Pure Python project where you want Bandit as a Python-specialised second opinion alongside Semgrep’s broader engine.

Frequently Asked Questions

Is Semgrep better than Bandit for Python?
Semgrep covers more rule patterns and is easier to customise. Bandit is Python-specialised with rules curated by Python security researchers since 2014. For pure Python projects, both tools find overlapping issues. Polyglot teams pick Semgrep for one engine across every language; Python-only shops often run both.
Is Bandit free?
Yes, Bandit is fully open source under the Apache 2.0 license with no paid tiers. Install via pip and run from CLI or pre-commit. Semgrep’s CE engine is open source under LGPL-2.1 (with the Opengrep community fork on the same license). Semgrep AppSec Platform adds managed rules and a SaaS dashboard behind paid tiers.
Can Semgrep replace Bandit entirely for Python?
For most teams, yes. Semgrep’s Python ruleset covers the same categories Bandit hits: hardcoded passwords, weak crypto, SSL verification disabled, shell injection, SQL injection, and deserialization risks. Some Python-specific Bandit plugins lack direct Semgrep equivalents. In those cases, run Bandit alongside Semgrep on Python files only.
Which has more rules, Bandit or Semgrep?
Semgrep has many more rules in absolute terms. The public Semgrep registry hosts thousands of rules across 30+ languages. Bandit has around 90 plugins covering Python-specific patterns curated since 2014. Per-language, Bandit’s Python ruleset is dense; Semgrep’s Python ruleset is broader because it includes generic SAST patterns.
How hard is it to write custom rules in Bandit vs Semgrep?
Semgrep custom rules are YAML using a Python-like pattern syntax, and most security engineers can write a useful rule in 10 minutes. Bandit custom plugins are Python modules that walk the Bandit AST API, closer to writing a small linter. For teams writing custom rules regularly, Semgrep is much less friction.
Suphi Cankurt

9+ years in application security. Reviews and compares 201 AppSec tools across 12 categories to help teams pick the right solution. More about me →