Loading...
Loading...
This skill should be used when the user asks to "scan Python code for security issues", "set up Bandit", "configure bandit security linting", "fix bandit warnings", or needs guidance on Python static security analysis with Bandit.
npx skill4agent add the-perfect-developer/the-perfect-opencode python-bandit# Base installation
pip install bandit
# With TOML config support (pyproject.toml)
pip install "bandit[toml]"
# With SARIF output (for GitHub Advanced Security)
pip install "bandit[sarif]"
# With baseline support
pip install "bandit[baseline]"astbandit -r path/to/project/bandit -r . --severity-level high
# or shorthand: -lll (high), -ll (medium+), -l (low+)
bandit -r . -lllbandit -r . --confidence-level high
# shorthand: -iii (high), -ii (medium+), -i (low+)bandit -r . -t B105,B106,B107 # hardcoded password checks onlybandit -r . -s B101 # skip assert_used (common in tests)bandit examples/*.py -p ShellInjectioncat myfile.py | bandit -bandit -r . -n 3[tool.bandit]
exclude_dirs = ["tests", "migrations", "venv"]
skips = ["B101"] # assert_used — acceptable in test suites
tests = [] # empty = run all (minus skips)bandit -c pyproject.toml -r .[bandit]
exclude = tests,migrations
skips = B101,B601
tests = B201,B301.bandit-r-cexclude_dirs: ['tests', 'path/to/file']
tests: ['B201', 'B301']
skips: ['B101', 'B601']
# Override plugin-specific defaults
try_except_pass:
check_typed_exception: truebandit -c bandit.yaml -r .bandit-config-generator > bandit.yaml
# Then edit — remove sections you don't need, adjust defaults# nosecself.process = subprocess.Popen('/bin/echo', shell=True) # nosecself.process = subprocess.Popen('/bin/ls *', shell=True) # nosec B602, B607assert yaml.load("{}") == [] # nosec assert_usedbandit -r . -f json -o report.json # JSON (required for baseline)
bandit -r . -f sarif -o report.sarif # SARIF (GitHub Advanced Security)
bandit -r . -f csv -o report.csv # CSV
bandit -r . -f xml -o report.xml # XML
bandit -r . -f html -o report.html # HTML
bandit -r . -f screen # Terminal (default)
bandit -r . -f yaml -o report.yaml # YAML# 1. Generate a baseline from the current state of the codebase
bandit -r . -f json -o .bandit-baseline.json
# 2. Commit the baseline to version control
git add .bandit-baseline.json
# 3. Future scans compare against the baseline
bandit -r . -b .bandit-baseline.json| Range | Category |
|---|---|
| B1xx | Miscellaneous |
| B2xx | App/framework misconfiguration |
| B3xx | Blacklisted calls |
| B4xx | Blacklisted imports |
| B5xx | Cryptography |
| B6xx | Injection |
| B7xx | XSS |
subprocessshell=Truepicklemarshalyaml.load()Loadermark_safepython -Oassert# Bad
assert user.is_admin, "Not authorized"
# Good
if not user.is_admin:
raise PermissionError("Not authorized")# Bad
password = "hunter2"
connect(password="secret")
# Good — read from environment or secrets manager
import os
password = os.environ["DB_PASSWORD"]# Bad
import hashlib
hashlib.md5(data)
# Good — use SHA-256 or higher for security contexts
hashlib.sha256(data)
# If MD5 is for non-security use (checksums), suppress with comment:
hashlib.md5(data).hexdigest() # nosec B324 — used for cache key, not security# Bad — arbitrary code execution risk
import yaml
yaml.load(data)
# Good
yaml.safe_load(data)
# or
yaml.load(data, Loader=yaml.SafeLoader)# Bad — shell injection vector
subprocess.Popen(user_input, shell=True)
# Good — pass args as a list, avoid shell
subprocess.Popen(["ls", "-l", path])# Bad
query = "SELECT * FROM users WHERE name = '" + name + "'"
# Good — use parameterized queries
cursor.execute("SELECT * FROM users WHERE name = ?", (name,))# Bad
requests.get(url, verify=False)
# Good
requests.get(url) # verify=True by default
requests.get(url, verify="/path/to/ca-bundle.crt")# nosecskipsreferences/plugin-reference.mdreferences/ci-cd-integration.md