Skip to content

Best SAST Tools for Python in 2026

Suphi Cankurt

Written by Suphi Cankurt

Key Takeaways
  • Bandit is the default Python SAST starting point — purpose-built for Python, 47 AST checks, runs in seconds, free. Add it to pre-commit before adding anything else.
  • Semgrep's Python ruleset and Bandit complement each other well. Bandit has native Python AST depth; Semgrep adds cross-language support, custom rule authoring, and the community registry.
  • CodeQL provides the deepest Python data flow analysis — tracking taint through Django, Flask, and custom code paths — but requires GitHub Advanced Security for private repos.
  • Pyright and Ruff are type checkers and linters with security-relevant checks, not full SAST tools. They catch misconfigurations and unsafe patterns that pure SAST tools miss, especially in typed Python codebases.
  • For production Python services, the most effective free stack is: Bandit + Semgrep in CI, Pyright for type safety, CodeQL on the main branch via GitHub Actions, and Snyk Code if you want commercial-grade taint analysis.

Python is one of the fastest-growing languages in enterprise codebases — web services, ML pipelines, data processing, infrastructure automation — and its dynamic nature creates SAST challenges that tools built for Java or C++ handle poorly. This guide compares 8 SAST tools with strong Python support: Bandit, Semgrep, Snyk Code, SonarQube, CodeQL, Pyright, Ruff, and Pylint security plugins.

Looking for the full SAST landscape? This guide focuses on Python-specific coverage. For all 50+ SAST tools including enterprise platforms, see the complete SAST tools list or the open source SAST tools guide.

Why Python SAST is different

Python’s dynamic typing, duck typing, and late binding mean that traditional type-inference-based SAST approaches (common in Java and C# scanners) work less reliably. A Python SAST tool needs AST-based pattern matching plus data flow analysis that handles Python idioms: list comprehensions, generators, decorators, and framework-specific sinks like Flask routes or Django ORM queries.

The other Python-specific concern is supply chain. Python projects lean heavily on PyPI. SAST tools for Python often pair naturally with SCA tools for Python to cover both application code and dependency vulnerabilities in a single pipeline.

The major Python-specific vulnerability patterns that SAST tools target include SQL injection via string-formatted queries, deserialization attacks via pickle and yaml.load, insecure use of subprocess and os.system, hardcoded secrets, SSRF through requests without validation, and insecure template rendering in Flask and Jinja2.


Top SAST tools for Python

1. Bandit

Bandit is the Python-specific SAST tool most developers reach for first. It was built by OpenStack developers to catch common Python security issues and is now maintained under the PyCQA umbrella.

What Bandit does well: 47 AST-based checks targeting Python-specific patterns — subprocess shell injection, pickle deserialization, hardcoded passwords, weak cryptography (MD5, SHA1, DES), use of assert for security, and insecure use of tempfile. Because it is Python-specific, it understands Python idioms that generic tools misinterpret.

Where Bandit falls short: No inter-procedural data flow analysis. It cannot trace taint from a Flask request argument through helper functions to a database query across files. It also has no support for non-Python files in the repo.

Best fit: Any Python project, especially as the first CI check. Lightweight enough to run on every commit without slowing the pipeline.

Bandit SAST scanner terminal output showing Python security issues with severity ratings
Bandit terminal output listing detected Python security issues by severity (HIGH/MEDIUM/LOW) and confidence level

2. Semgrep

Semgrep supports Python through a structural pattern-matching engine that understands Python syntax — not just regular expressions. The Semgrep Registry includes Python-specific rulesets covering OWASP Top 10, Flask security, Django ORM injection, Jinja2 template injection, and more.

What Semgrep does well: Custom Python rules in YAML are readable and fast to write. The community registry includes Bandit-compatible rules so you can consolidate tooling. Semgrep’s taint analysis (available in the community tier with --pro on public repos) can track user input across function calls within a file.

Where Semgrep falls short: Deep cross-file inter-procedural analysis requires Semgrep Code (the paid platform tier). The community engine is strong but stops at file boundaries for complex taint flows.

Best fit: Teams that want one SAST scanner for a multi-language codebase, or Python teams that need to write custom detection rules for proprietary frameworks.

Semgrep scan results showing Python security rule matches with file locations and rule IDs
Semgrep scanning a Python codebase with community security rules, showing matched patterns and severity

3. Snyk Code

Snyk Code provides commercial-grade Python SAST with real-time feedback in the IDE. Its Python analysis engine understands Django, Flask, FastAPI, and SQLAlchemy patterns, covering taint flows that cross function and file boundaries.

What Snyk Code does well: Data flow analysis across files is the primary advantage over Bandit and Semgrep CE. Snyk Code can trace a tainted request.args.get() value through multiple helper functions to a SQL query or a subprocess.run() call. The IDE integration (VS Code, PyCharm) surfaces issues inline as you type.

Where Snyk Code falls short: The free tier is limited to the IDE. CI/CD integration with full taint analysis requires a paid plan. It is a SaaS tool — source code is sent to Snyk’s infrastructure for analysis, which matters for air-gapped or classified environments.

Best fit: Development teams that want commercial-quality Python taint analysis with an IDE-first workflow and developer-friendly fix guidance.

Snyk Code showing Python taint flow analysis with data flow path from source to vulnerable sink
Snyk Code tracing a tainted data flow through Python code from user input to a vulnerable sink, with fix guidance

4. SonarQube

SonarQube Community Edition supports Python with a dedicated rule set covering injection, SSRF, insecure deserialization, weak cryptography, and improper error handling. It combines security rules with code quality checks (coverage, duplication, complexity) in one platform.

What SonarQube does well: The combination of security and quality in one scanner reduces tool sprawl. SonarQube’s Python support includes rules for Django, Flask, and standard library misuse. Quality gates — blocking PRs that introduce new issues — are well-implemented.

Where SonarQube falls short: Taint analysis across function boundaries requires Developer Edition or higher (commercial). Community Edition catches pattern-based issues but misses complex data flow vulnerabilities.

Best fit: Teams that already use SonarQube for code quality and want to add security coverage without a separate tool.

SonarQube security issues dashboard showing Python vulnerabilities by severity and rule category
SonarQube displaying Python security findings organized by severity, with OWASP and CWE category mappings

5. CodeQL

CodeQL models Python code as a queryable database and ships queries for Python taint tracking, SQL injection in Django and SQLAlchemy, SSRF, template injection, insecure deserialization, and more. The analysis follows user input across the entire codebase regardless of how many functions it passes through.

What CodeQL does well: Deep Python inter-procedural data flow analysis. CodeQL’s Python model understands Django’s ORM, Flask’s request object, and common Python framework patterns. Results are highly accurate because the engine models actual Python semantics rather than matching text patterns.

Where CodeQL falls short: Analysis runs slower than pattern-based tools. It adds 5–15 minutes to a CI pipeline for medium-sized Python projects. Setup requires understanding QL queries or using the bundled defaults, which is a steeper learning curve than running bandit ..

Best fit: Python web applications and API services where complex injection vulnerabilities in Django, Flask, or FastAPI are the primary concern, and where CI pipeline time allows for a deeper scan.

GitHub CodeQL code scanning alert detail showing Python security vulnerability with data flow path
CodeQL code scanning alert in GitHub showing a Python vulnerability with taint flow path from source to sink

6. Pyright

Pyright is Microsoft’s static type checker for Python. It is not a dedicated SAST tool, but it catches a category of issues that pure security scanners miss: type mismatches, missing None checks, unresolved attributes, and incorrect API usage that can lead to runtime errors or security-relevant logic bugs.

What Pyright does well: Fast, accurate type inference for Python 3.x. Pyright’s strict mode catches potential None dereferences, incorrect type narrowing, and use of deprecated or undefined attributes — all of which contribute to security-relevant behavior. It is the type layer that Bandit and Semgrep lack.

Where Pyright falls short: No security rule set. It does not detect injection, deserialization, or secrets. Its value in a SAST stack is catching the class of bugs that type errors represent, not replacing a security scanner.

Best fit: Typed Python codebases (those using mypy, pyright, or PEP 484 type annotations) where type safety overlaps with security correctness.


7. Ruff

Ruff is an extremely fast Python linter written in Rust that includes a subset of Bandit’s security rules (the S rule prefix). It is primarily a linter and code quality tool, but its Bandit-compatible checks — subprocess injection, hardcoded passwords, insecure hash functions — run in under a second on large codebases.

What Ruff does well: Speed. Ruff replaces Flake8, isort, pyupgrade, and parts of Bandit in one tool with near-instant execution. Teams that already run Ruff can enable the S rules and get basic security coverage without adding another dependency.

Where Ruff falls short: It covers a subset of Bandit’s checks — roughly 50 of Bandit’s rules as of 2026. No data flow analysis. It is not a replacement for a dedicated SAST tool.

Best fit: Python teams using Ruff as their primary linter who want basic security checks included without a separate Bandit invocation.


8. Pylint security plugins

Pylint has an ecosystem of security-focused plugins — most notably pylint-django and dlint — that extend it with Django-specific checks and broader security rules covering insecure functions, hardcoded credentials, and unsafe imports.

What Pylint security plugins do well: If your team already runs Pylint, adding dlint (a Pylint plugin from Duo Security) adds security checks without changing the pipeline. It covers SQL injection patterns, insecure subprocess calls, and insecure deserialization.

Where Pylint security plugins fall short: Plugin quality and maintenance varies. dlint has not seen active development in recent years. Coverage is narrower than dedicated SAST tools.

Best fit: Legacy Python projects already on Pylint where changing the toolchain is not feasible.


Comparison table

ToolTypePython DepthTaint AnalysisLicenseBest For
BanditSAST (Python-specific)Deep ASTNoneOpen sourceFirst Python security check
SemgrepSAST (multi-language)Strong patternsLimited (single-file)Open source / CommercialCustom rules, multi-language
Snyk CodeSAST (commercial)Deep + frameworksCross-fileCommercial (free IDE tier)Developer-first taint analysis
SonarQubeSAST + qualityModeratePaid tiers onlyOpen source / CommercialQuality + security combined
CodeQLSAST (deep analysis)Very deepCross-projectFree (public) / CommercialComplex Django/Flask taint
PyrightType checkerType-levelNoneOpen sourceTyped Python codebases
RuffLinter + subset SASTBasic (Bandit subset)NoneOpen sourceSpeed-focused teams
Pylint + dlintLinter + pluginsLimitedNoneOpen sourceLegacy Pylint users

How to choose for your use case

Start-up or small team on a budget: Run Bandit and Semgrep together in CI. They are free, fast, and complementary. Add Pyright if you use type annotations. That covers the majority of Python security surface without spending anything.

Growing team with a Django or Flask web app: Bandit and Semgrep for the developer loop, CodeQL on the main branch via GitHub Actions (free for public repos, discounted for private), and SonarQube CE as a quality gate. This gives you deep data flow analysis on the critical path without a commercial tool.

Enterprise or compliance-driven team: Snyk Code or SonarQube Developer Edition adds commercial-grade taint analysis with IDE integration, audit trails, and RBAC. If your Python code handles sensitive data, inter-procedural taint analysis is not optional — it catches the SQL injection and SSRF patterns that pattern-based tools miss. See the enterprise SAST tools guide for the broader landscape.

ML or data pipeline team: Bandit plus Semgrep cover most issues. Focus on pickle deserialization rules (Bandit B301-B303) and any S3 or cloud SDK usage patterns in your Semgrep configuration.

Monorepo with Python + JavaScript: Semgrep is the natural anchor — it handles both in one scanner. Add Bandit for Python-specific depth.


Open source vs commercial

The free Python SAST stack — Bandit, Semgrep CE, CodeQL (public repos) — covers the pattern-matching tier well. The gap versus commercial tools is primarily in cross-file taint analysis and in the quality of results for framework-specific Python code.

Snyk Code and SonarQube Developer Edition both perform inter-procedural taint analysis that follows user input through multiple function calls and files. For Flask and Django applications processing untrusted input, this matters: a tainted request.args value passing through three helper functions before reaching a database call will likely be missed by Bandit but caught by Snyk Code.

CodeQL bridges the gap for teams that need deep analysis without a commercial license — but it is free only for public repositories via GitHub Advanced Security. Private repos require a GitHub Enterprise license.

For a more detailed look at the free and open-source options, see the open source SAST tools guide. For buying considerations around commercial tools, see SAST vs SCA: which do you need first.


FAQ

This guide is part of the resource hub.

Frequently Asked Questions

What is the best free SAST tool for Python?
Bandit is the most widely adopted free Python SAST tool — it is purpose-built for Python, ships with 47 AST-based checks, and integrates with pre-commit hooks in under five minutes. For teams that want broader language coverage alongside Python, Semgrep Community Edition covers Python plus 30+ other languages with 3,000+ community rules. Running both together takes under two minutes on most projects and costs nothing.
Is Bandit still maintained?
Yes. Bandit is maintained under the PyCQA (Python Code Quality Authority) umbrella. After a period of slower activity, it is actively receiving bug fixes and new checks. It remains the de facto Python-specific SAST tool for open-source and developer workflows, and it is pre-installed in many CI templates.
Can Semgrep replace Bandit for Python?
Semgrep can cover most of what Bandit checks through its Python ruleset — including the Bandit-compatible rules in the community registry. But the two tools have different strengths. Bandit has deep Python AST awareness built specifically for the language. Semgrep’s strength is extensibility: custom rules in YAML and multi-language coverage in one scanner. For a Python-only project, running Bandit and Semgrep together costs nothing and covers more ground than either alone.
Does SonarQube support Python?
Yes. SonarQube Community Edition supports Python with security rules covering injection, insecure deserialization, SSRF, and other OWASP categories. The commercial editions (Developer and above) add taint analysis that traces user input across functions and files. SonarQube also ships Python code quality checks for coverage, duplication, and maintainability alongside its security rules.
Is CodeQL useful for Python?
CodeQL is the strongest option for deep Python data flow analysis — it models how user input flows through the entire codebase, including through Django ORM calls, Flask routes, and custom serializers. It is available free for public repos via GitHub Advanced Security, and costs money for private repos. For Python projects where complex taint flows matter (API services, web apps processing untrusted input), CodeQL is harder to match on detection depth.
Suphi Cankurt

Years in application security. Reviews and compares 209 AppSec tools across 11 categories to help teams pick the right solution. More about me →