Bandit is a security linter for Python code, designed to find common security issues and vulnerabilities in your codebase.
Bandit scans Python code for common security issues such as:
- Hardcoded passwords and secrets
- SQL injection vulnerabilities
- Command injection vulnerabilities
- Insecure use of cryptographic functions
- Use of potentially dangerous functions
- Insecure file permissions
- And many other security concerns
It works by parsing the abstract syntax tree (AST) of Python files and running a series of plugins that look for specific patterns associated with security issues.
Bandit is included as a development dependency:
# Install with other development dependencies
uv sync --devTo install it directly:
uv pip install banditIn this project, Bandit is used to:
- Identify potential security vulnerabilities in the codebase
- Enforce security best practices
- Prevent common security mistakes
- Run as part of the pre-commit hooks and CI/CD pipeline
Bandit is configured in the pyproject.toml file:
[tool.bandit]
exclude_dirs = ["tests", ".venv", ".git"]
skips = ["B101"] # Skip assert statements warningThis configuration:
- Excludes test directories and virtual environments from scanning
- Skips the B101 check (use of assert statements), which is often a false positive in test code
Bandit is also configured as a poethepoet task:
[tool.poe.tasks]
bandit = "bandit -c pyproject.toml -r src --exclude tests,.venv,.git"To run Bandit on the project:
# Run via poethepoet
uv run poe bandit
# Run directly
uv run bandit -c pyproject.toml -r src# Scan a specific file
uv run bandit path/to/file.py
# Scan a directory recursively
uv run bandit -r path/to/directory
# Specify severity level
uv run bandit -r src -l high
# Specify confidence level
uv run bandit -r src -c medium
# Generate a report
uv run bandit -r src -f json -o bandit-report.json# Potentially problematic (assertions can be disabled with -O)
assert user.is_authenticated()
# Better approach
if not user.is_authenticated():
raise PermissionError("User not authenticated")# Dangerous
exec(user_input)
# Better approach
# Avoid exec entirely, use safer alternatives# Insecure
open("sensitive.txt", "w").write("secret")
# More secure
import os
with open("sensitive.txt", "w") as f:
os.chmod("sensitive.txt", 0o600) # Owner read/write only
f.write("secret")# Insecure
password = "hardcoded_password"
# Better approach
import os
password = os.environ.get("PASSWORD")# Insecure
import pickle
data = pickle.loads(user_input) # Arbitrary code execution risk
# Better approach
import json
data = json.loads(user_input)- Run Bandit regularly: Include Bandit in your pre-commit hooks and CI/CD pipeline.
- Address high-severity issues immediately: High-severity issues with high confidence should be fixed as soon as possible.
- Review false positives: Some issues flagged by Bandit may be false positives. Review them carefully and add skips only when necessary.
- Use context-specific configurations: Different parts of your codebase may need different security checks.
- Keep Bandit updated: Security tools should be kept up to date to catch the latest known vulnerabilities.
If you're getting too many false positives:
- Review the issues to ensure they're actually false positives
- Add specific skips for the relevant checks in
pyproject.toml - Use inline skips for specific lines:
# nosecor# nosec B101
If you're having issues integrating Bandit with other tools:
- Ensure you're using compatible versions
- Check that your configuration files are correctly formatted
- Try running Bandit directly to isolate the issue