Updated Jul 14, 2026

Static Code Analysis

Catch Python security bugs from the AST

AST-based security checks for Python source.

Agent

overview

What bandit does

bandit reads Python source, builds an AST, and runs security plugins against the nodes. That catches hardcoded passwords, shell injection, weak crypto, and unsafe deserialization that a text grep misses or over-reports.

Tune the run: -ll or -lll set a severity floor, --skip drops noisy test IDs, --baseline keeps only new findings, and -f chooses csv, json, xml, html, and other report shapes.

Trickest provides bandit as a managed Static Code Analysis node. Feed a FILE or FOLDER of Python source, often with --recursive; it writes FILE and FOLDER findings for triage or merge with dynamic scanner output.

source github.com/PyCQA/bandit

use cases

Where bandit fits

Scan a Python repository for security bugs

Point bandit at a source folder with --recursive and let its plugins surface injection, weak crypto, and hardcoded secrets across the whole codebase.

Gate a pipeline on new findings only

Compare against a baseline JSON report with --baseline so previously accepted issues stay quiet and the run flags only fresh problems.

Tune the noise with severity and test IDs

Raise the severity floor with -ll or -lll and drop noisy plugins with --skip so a run returns the high-signal findings worth acting on.

Feed results into shared triage

Emit JSON or XML with -f and route bandit findings into the same table and reporting flow as dynamic scanner output for one risk view.

reference

bandit inputs and flags

23 inputs
NameTypeFlagDescription
targets-folderFOLDERtargetsSource folder to scan.
targets-fileFILEtargetsSource file(s) to scan.
recursive-targetFOLDER--recursiveFind and process files in subdirectories.
output-formatSTRING-fOutput format: csv, custom, html, json, screen, txt, xml, or yaml.
level-mediumSTRING-llReport only issues at MEDIUM severity or higher (-l low, -lll high).
baselineFILE--baselinePath of a baseline JSON report to compare against.
skip-idSTRING--skipComma-separated list of test IDs to skip.
exit-zeroBOOLEAN--exit-zeroExit with 0 even when results are found.

Showing key inputs. bandit exposes 23 inputs in total.

Full flag reference (23 inputs)
NameTypeFlagDescription
debugBOOLEAN-dTurn on debug mode.
quietBOOLEAN-qOnly show output in the case of an error.
profileSTRING--profileProfile to use (defaults to executing all tests).
skip-idSTRING--skipComma-separated list of test IDs to skip.
test-idSTRING--testsComma-separated list of test IDs to run.
verboseBOOLEAN--verboseOutput extra information like excluded and included files.
baselineFILE--baselinePath of a baseline report to compare against (only JSON-formatted files are accepted).
ini-fileFILE--iniPath to a .bandit file that supplies command line arguments.
aggregateSTRING--aggregateAggregate output by vulnerability (default) or by filename.
exit-zeroBOOLEAN--exit-zeroExit with 0, even when results are found.
level-lowSTRING-lReport only issues at LOW severity or higher.
confidenceBOOLEAN--confidenceReport only issues at a given confidence level or higher.
level-highSTRING-lllReport only issues at HIGH severity or higher.
config-fileFILE--configfileOptional config file to use for selecting plugins and overriding defaults.
ignore-nosecBOOLEAN--ignore-nosecDo not skip lines with # nosec comments.
level-mediumSTRING-llReport only issues at MEDIUM severity or higher.
msg-templateSTRING--msg-templateSpecify output message template (only usable when output-format is set to custom).
number-linesSTRING--numberMaximum number of code lines to output for each issue.
targets-fileFILEtargetsSource file(s) to scan.
exclude-pathsSTRING--excludeComma-separated list of paths (glob patterns supported) to exclude from the scan, in addition to the config file excludes (default: .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg).
output-formatSTRING-fOutput format: csv, custom, html, json, screen, txt, xml, or yaml.
targets-folderFOLDERtargetsSource folder to scan.
recursive-targetFOLDER--recursiveFind and process files in subdirectories.

example

Run bandit

bandit · command
# recursively scan a source tree, medium severity and up, JSON reportbandit -r ./src -ll -f json -o findings.json
sample output
Run started:2026-07-14 09:12:03Test results:>> Issue: [B105:hardcoded_password_string] Possible hardcoded password: 'changeme'   Severity: Low   Confidence: Medium   Location: ./src/config.py:14:14>> Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified.   Severity: High   Confidence: High   Location: ./src/tasks.py:52:8Code scanned: 1284 lines across 9 files, 2 issues (1 High, 1 Low)

guidance

Choosing bandit

Use bandit when the target is Python source, not a running app. It reasons about code; dynamic scanners test the deployed service, so pair both for coverage. For many languages with one engine, reach for semgrep instead.

semgrep

Pattern-based static analysis across many languages. bandit is Python-only and ships Python-specific plugins out of the box.

gosec

Equivalent security linter for Go. Same role, different language.

dawnscanner

Security scanner for Ruby web apps. Sibling tool for a different stack.

faq

bandit questions

Plugins flag hardcoded passwords, shell and command injection (subprocess with shell=True, os.system), weak crypto such as MD5, unsafe deserialization (pickle, yaml.load), SQL string building, and assert use in production. Each finding carries a Bxxx test ID, severity, and confidence.

Run bandit yourself

Python source feeds bandit, which builds an AST, runs its security plugins, and writes the findings as a queryable output.

Facts on this page come from the live Trickest tool library.