Bandit Python Seguridad Linter Cheat Sheet¶
"Clase de la hoja" idbutton id="bandit-copy-btn" class="copy-btn" onclick="copyAllCommands()" Copiar todos los comandos id="bandit-pdf-btn" class="pdf-btn" onclick="generatePDF()" Generar PDF seleccionado/button ■/div titulada
Sinopsis¶
Bandit es un dispositivo de seguridad diseñado para encontrar problemas comunes de seguridad en el código Python. Analiza el código fuente Python e identifica posibles vulnerabilidades de seguridad escaneando patrones conocidos y anti-patterns. Bandit es ampliamente utilizado en los oleoductos DevSecOps para captar cuestiones de seguridad a principios del proceso de desarrollo, lo que lo convierte en un instrumento esencial para el desarrollo de Python seguro.
NOVEDAD Nota: Bandit está diseñado para identificar posibles cuestiones de seguridad y debe ser utilizado como parte de una estrategia integral de pruebas de seguridad. Puede producir falsos positivos y debe combinarse con otros métodos de prueba de seguridad.
Instalación¶
Usando pip¶
# Install Bandit
pip install bandit
# Install with additional formatters
pip install bandit[toml]
# Install development version
pip install git+https://github.com/PyCQA/bandit.git
# Verify installation
bandit --version
Usando conda¶
# Install from conda-forge
conda install -c conda-forge bandit
# Create dedicated environment
conda create -n security-tools bandit
conda activate security-tools
Utilizando gestores de paquetes¶
# Ubuntu/Debian
sudo apt update
sudo apt install bandit
# CentOS/RHEL/Fedora
sudo dnf install bandit
# or
sudo yum install bandit
# macOS with Homebrew
brew install bandit
# Arch Linux
sudo pacman -S bandit
Docker Instalación¶
# Pull official Bandit image
docker pull securecodewarrior/bandit
# Run Bandit in container
docker run --rm -v $(pwd):/code securecodewarrior/bandit bandit -r /code
# Build custom image
cat > Dockerfile ``<< 'EOF'
FROM python:3.9-slim
RUN pip install bandit
WORKDIR /app
ENTRYPOINT ["bandit"]
EOF
docker build -t custom-bandit .
docker run --rm -v $(pwd):/app custom-bandit -r .
Uso básico¶
Escáneos simples¶
# Scan a single file
bandit example.py
# Scan a directory recursively
bandit -r /path/to/project
# Scan current directory
bandit -r .
# Scan with verbose output
bandit -v -r .
# Scan specific files
bandit file1.py file2.py file3.py
# Scan with specific confidence level
bandit -r . -i # Show only high confidence issues
bandit -r . -ii # Show medium and high confidence issues
bandit -r . -iii # Show all confidence levels
Formatos de salida¶
# JSON output
bandit -r . -f json
# XML output
bandit -r . -f xml
# CSV output
bandit -r . -f csv
# HTML output
bandit -r . -f html
# YAML output
bandit -r . -f yaml
# Custom output
bandit -r . -f custom --msg-template "\\\{abspath\\\}:\\\{line\\\}: \\\{test_id\\\}[bandit]: \\\{severity\\\}: \\\{msg\\\}"
# Save output to file
bandit -r . -f json -o bandit-report.json
bandit -r . -f html -o bandit-report.html
Filtración de severidad y confianza¶
# Filter by severity (LOW, MEDIUM, HIGH)
bandit -r . -l # Low severity and above
bandit -r . -ll # Medium severity and above
bandit -r . -lll # High severity only
# Filter by confidence (LOW, MEDIUM, HIGH)
bandit -r . -i # High confidence only
bandit -r . -ii # Medium and high confidence
bandit -r . -iii # All confidence levels
# Combine severity and confidence
bandit -r . -ll -ii # Medium+ severity, Medium+ confidence
Configuración¶
Archivo de configuración (.bandit)¶
# .bandit configuration file
tests: ['B201', 'B301']
skips: ['B101', 'B601']
exclude_dirs: ['*/tests/*', '*/venv/*', '*/env/*']
# Severity levels: LOW, MEDIUM, HIGH
severity: MEDIUM
# Confidence levels: LOW, MEDIUM, HIGH
confidence: MEDIUM
# Output format
format: json
# Include line numbers
include_line_numbers: true
# Aggregate results
aggregate: vuln
pyproject.toml Configuración¶
[tool.bandit]
exclude_dirs = ["tests", "venv", ".venv", "env", ".env"]
tests = ["B201", "B301"]
skips = ["B101", "B601"]
[tool.bandit.assert_used]
skips = ['*_test.py', '*test_*.py']
Configuración de línea de comandos¶
# Exclude directories
bandit -r . --exclude /tests/,/venv/,/.venv/
# Skip specific tests
bandit -r . --skip B101,B601
# Run specific tests only
bandit -r . --tests B201,B301
# Exclude files by pattern
bandit -r . --exclude "*/migrations/*,*/settings/*"
# Include only specific file patterns
bandit -r . --include "*.py"
Uso avanzado¶
Selección de pruebas personalizadas¶
# List all available tests
bandit -l
# Get detailed test information
bandit --help-tests
# Run specific vulnerability tests
bandit -r . --tests B101 # assert_used
bandit -r . --tests B102 # exec_used
bandit -r . --tests B103 # set_bad_file_permissions
bandit -r . --tests B104 # hardcoded_bind_all_interfaces
bandit -r . --tests B105 # hardcoded_password_string
# Skip specific tests
bandit -r . --skip B101,B102,B103
# Test categories
bandit -r . --tests B1* # All B1xx tests
bandit -r . --tests B2* # All B2xx tests
bandit -r . --tests B3* # All B3xx tests
Escáner de referencia y progresivo¶
# Create baseline
bandit -r . -f json -o baseline.json
# Compare against baseline
bandit -r . -f json|bandit-baseline -b baseline.json
# Progressive scanning (only new issues)
bandit -r . --baseline baseline.json
# Update baseline
bandit -r . -f json -o new-baseline.json
Integración con Git¶
# Pre-commit hook script
#!/bin/bash
# .git/hooks/pre-commit
bandit -r . -ll -ii
if [ $? -ne 0 ]; then
echo "Bandit found security issues. Commit aborted."
exit 1
fi
# Make executable
chmod +x .git/hooks/pre-commit
# Git hook with specific files
#!/bin/bash
# Check only modified Python files
git diff --cached --name-only --diff-filter=ACM|grep '\.py
## CI/CD Integration
### GitHub Actions
```yaml
# .github/workflows/security.yml
nombre: Security Scan
[push, pull_request]
empleo:
bandido:
ubuntu-latest
pasos:
- usos: acciones/checkout@v3
- Nombre: Configurar Python
usos: acciones/setup-python@v4
con:
python-version: '3.9'
- nombre: Install Bandit
run: pip install bandit[toml]
- nombre: Run Bandit
run: bandit -r. -f json -o bandit-report.json
- nombre: Subir resultados
usos: acciones/upload-artifact@v3
con:
nombre: bandit-report
path: bandit-report.json
- nombre: Bandit Report
usos: tj-actions/bandit@v5.1
con:
opciones: "-r. -f json"
exit_zero: verdadero
__CODE_BLOCK_13_yaml
# .gitlab-ci.yml
etapas:
- seguridad
bandido:
etapa: seguridad
imagen: pitón:3.9
antes_script:
- pip install bandit[toml]
script:
- bandit -r. -f json -o bandit-report.json
artefactos:
informes:
sast: bandit-report.json
caminos:
- bandit-report.json
expire_in: 1 semana
allow_failure: verdadero
Jenkins Pipeline¶
// Jenkinsfile
tubería \\ {}
cualquier agente
etapas \\ {}
stage('Security Scan') \\ {}
pasos \\{
script \\{
sh 'pip install bandit[toml] '
sh 'bandit -r. -f json -o bandit-report.json '
\ '
\ '
post \\ {}
siempre \ ' {}
archivoArtifacts artifacts: 'bandit-report.json', huella dactilar: true
publicHTML([
permitir Desaparecido: falso,
SiempreLinkToLastBuild: verdadero,
all: verdadero,
informe '.',
reportes: 'bandit-report.html',
reportName: 'Bandit Security Report '
])
\ '
\ '
\ '
\ '
\ '
Azure DevOps¶
# azure-pipelines.yml
gatillo:
- principal
piscina:
vmImage: 'ubuntu-latest '
pasos:
- tarea: UsePythonVersion@0
entradas:
versión Espec: '3.9'
- script:
pip install bandit[toml]
bandit -r. -f json -o $(Agent.TempDirectory)/bandit-report.json
displayName: 'Run Bandit Security Scan '
- task: PublishTestResults@2
entradas:
testResultadosFiles: '$(Agent.TempDirectory)/bandit-report.json '
prueba RunTitle: 'Bandit Security Scan '
Common Vulnerability Patterns¶
Hardcoded Passwords (B105, B106, B107)¶
# BAD: contraseña codificada
contraseña = "secret123"
api_key = "abc123def456"
# BUENO: variables ambientales
importaciones o
contraseña = os.environ.get('PASSWORD')
api_key = os.environ.get('API_KEY')
# BUENO: Archivo de configuración
import configparser
config = confidente.ConfigParser()
config.read('config.ini')
contraseña = config.get('database', 'password')
SQL Injection (B608)¶
# BAD: String formatting
query = "SELECT * DESDE usuarios WHERE id = % user_id" % user_id
query = f"SELECT * DESDE los usuarios WHERE id = \\{user_id\\}"
# BUENO: Consultas paramétricas
cursor.ejecute("SELECT * DESDE users WHERE id = %s", (user_id,))
cursor.execute("SELECT * DESDE users WHERE id = ?", (user_id,))
Command Injection (B602, B605, B606, B607)¶
# BAD: Inyección de Shell
importaciones o
os.system(f"ls \\{user_input\\\}")
os.popen(f"grep \\{pattern\\\\\\\\\\\\}")
# BUENO: Subproceso con lista
subprocesos de importación
subprocess.run(['ls', user_input])
subprocess.run(['grep', patrón, nombre de archivo])
__CODE_BLOCK_19_python
# BAD: Predictable random
importación aleatoria
token = random.randint(1000, 9999)
# BUENO: Cryptographically secure
secretos de importación
token = secrets.randbelow(9999)
secure_token = secrets.token_hex(16)
Unsafe YAML Loading (B506)¶
# BAD: carga de YAML inseguro
importa yaml
datos = yaml.load(user_input)
# Bien: carga segura de YAML
datos = yaml.safe_load(user_input)
datos = yaml.load(user_input, Loader=yaml.SafeLoader)
__CODE_BLOCK_21_python
# custom_bandit_test.py
importado bandido
del bandido. Core import test_properties
@test_properties.test_id('B999')
@test_properties.checks('Call')
def custom_security_check(contexto):
""Comprobar el patrón de seguridad personalizado""
si context.call_function_name_qual == 'dangerous_function':
Regresar bandido. Cuestión
Severidad=banda. Muy bien.
Confianza. Muy bien.
texto="Uso de función peligrosa_ detectada",
lineno=context.node.lineno,
Plugin Development¶
# bandit_plugin.py
del bandido. core import extension_loader
def load_tests():
""Las pruebas personalizadas de carga""
[custom_security_check]
# Registro plugin
extension_loader.MANAGER.register_plugin('custom_tests', load_tests)
Using Custom Tests¶
# Pruebas personalizadas de carga
bandido -r. --tests custom_bandit_test.py
# Use plugin
bandido -r. --plugin bandit_plugin.py
Automation and Scripting¶
Automated Scanning Script¶
#!/usr/bin/env python3
# bandit_scanner.py
subprocesos de importación
importación json
importador sys
import argparse
de la importación de patlib Camino
Clase BanditScanner:
def __init__(self, project_path, config_file=None):
self.project_path = Path(project_path)
auto.config_file = config_file
self.results = \\{\\}
def run_scan(self, output_format='json', gravity='MEDIUM', confidence='MEDIUM'):
""Run Bandit scan con parámetros especificados"""
cmd
'banda', 'r', str(self.project_path),
'-f', output_format,
f'-l\\{self._severity_to_flag(severity)\\}',
f'-i\\{self._confidence_to_flag(confidence)\\} '
]
si auto.config_file:
cmd.extend(['--configfile', self.config_file])
Prueba:
resultado = subprocess.run(cmd, capture_output=True, text=True, check=False)
si output_format == 'json':
auto.resultos = json.loads(result.stdout) si resultado. stdout else
más:
auto.resultos = resultado.stdout
resultado de retorno. código de retorno == 0
excepto el subproceso. CalledProcess Error como e:
print(f"Error running Bandit: \\{e\\}")
regreso False
excepto Json. JSONDecode Error como e:
print(f"Error parsing JSON output: \\{e\\\}")
regreso False
def _severity_to_flag(self, gravity):
""Convertir la severidad de la bandera Bandit"""
mapeo = \ '{'LOW': '', 'MEDIUM': 'I', 'HIGH': 'll'\\'
mapeo de retorno. get(severity.upper(), 'l)
def _confidence_to_flag(self, confidence):
""Convertir la confianza en Bandit flag""
mapeo = \ '{'LOW': 'ii', 'MEDIUM': 'i', 'HIGH': ''\'
devolver mapping.get(confidence.upper(), 'i')
def get_summary(self):
""Obtenga un resumen del escaneo""
si no eststance(self.results, dict):
devolver "No hay resultados disponibles"
métricas = auto.results.get('metrics', \\{\\\})
Retorno
'total_lines': metrics.get('_totals', \\{\\\})get('loc', 0),
'total_issues': len(self.results.get('results', [])),
'high_severity': len([r for r in self.results.get('results', [])
si r.get('issue_severity') == 'HIGH']),
'medium_severity': len([r for r in self.results.get('results', [])
si r.get('issue_severity') == 'MEDIUM']),
'low_severity': len([r for r in self.results.get('results', [])
si r.get('issue_severity') == 'LOW')
\ '
def get_issues_by_severity(self, gravity='HIGH'):
""Consigue problemas filtrados por gravedad""
si no eststance(self.results, dict):
retorno []
retorno [eso para emisión en auto.results.get('results', [])
if issue.get('issue_severity') == gravity.upper()]
def generate_report(self, output_file='bandit_report.html'):
""Informe HTML de Generación"""
cmd
'banda', 'r', str(self.project_path),
'-f', 'html', '-o', output_file
]
si auto.config_file:
cmd.extend(['--configfile', self.config_file])
Prueba:
subprocess.run(cmd, check=True)
Retorno
excepto el subproceso. CalledProcess Error:
regreso False
def save_results(self, output_file='bandit_results.json'):
""Guardar resultados para archivar"""
si isinstance(self.results, dict):
con open(output_file, 'w') como f:
json.dump(self.results, f, indent=2)
más:
con open(output_file, 'w') como f:
f.write(str(self.results))
def main():
parser = argparse. ArgumentParser(descripción='Automated Bandit Scanner')
parser.add_argument('project_path', help='Path to project to scan')
parser.add_argument('--config', help='Bandit settings file')
parser.add_argument('--severity', default='MEDIUM',
opciones=['LOW', 'MEDIUM', 'HIGH'],
help='Minimum gravity level')
parser.add_argument('--confianza', default='MEDIUM',
opciones=['LOW', 'MEDIUM', 'HIGH'],
help='Minimum confidence level')
parser.add_argument('--output', help='Output file for results')
parser.add_argument('--report', help='Generate HTML report')
args = parser.parse_args()
escáner = BanditScanner(args.project_path, args.config)
print(f"Scanning \\{args.project_path\\}...")
éxito = escáner.run_scan(severity=args.severity, confidence=args.confidence)
si el éxito:
sumario = escáner.get_summary()
print(f"Scan completado con éxito!")
print(f"Total line of code: \\{summary['total_lines']\}")
print(f"Total issues found: \\{summary['total_issues']\")
print(f"Severidad alta: \\{summary['high_severity']\}")
print(f"Severidad media: \\{summary['medium_severity']\}")
print(f"Severidad mínima: \\{summary['low_severity']\}")
si args. Producto:
scanner.save_results(args.output)
print(f"Resultados guardados a \\{args.output\\})
si args.report:
si el escáner.generate_report(args.report):
print(f"HTML report generado: \\{args.report\\\}")
más:
print("Failed to generate HTML report")
# Exit with error code if high severity issues found
si el resumen ['high_severity'] 0:
print("High gravity issues found!")
sys.exit(1)
más:
print("Scan falló!")
sys.exit(1)
si __name__ == '__main__':
principal()
Batch Processing Script¶
#!/bin/bash
# batch_bandit_scan.sh
# Configuración
PROYECTOS_DIR="/path/to/projects"
REPORTS_DIR="/path/to/reports"
Fecha ♪
# Crear directorio de informes
mkdir -p "$REPORTS_DIR"
# Función para escanear el proyecto
scan_project() \{
proyecto local_path="$1"
local project_name=$(basename "$project_path")
local report_file="$REPORTS_DIR/$\{project_name\}_$\{DATE\}.json"
local html_report="$ REPORTS_DIR/$\{project_name\}_$\{DATE\}.html"
eco "Scanning $project_name..."
# Run Bandit scan
bandit -r "$project_path" -f json -o "$report_file" -ll -ii
bandit -r "$project_path" -f html -o "$html_report" -ll -ii
# Check for high severity issues
high_issues=$(jq '.results WordPressmap(select(.issue_severity == "HIGH")
si [ "$high_issues" -gt 0 ]; entonces
eco "Advertencia: $project_name tiene $high_issues problemas de alta gravedad!"
eco "$project_name" √Īo "$REPORTS_DIR/high_severity_projects.txt"
fi
eco "Scan completó para $project_name"
{\cHFF}
# Escanear todos los proyectos Python
encontrar "$PROJECTS_DIR" -nombre "*.py" -tipo f sometida while read -r file; do
project_dir=$(name "$file")
si [ ! -f "$project_dir/.bandit_scanned" ]; entonces
scan_project "$project_dir"
tacto "$project_dir/.bandit_scanned"
fi
hecho
eco "Bolveción completada. Informes guardados a $REPORTS_DIR"
Integration with IDEs¶
VS Code Integration¶
// .vscode/settings.json
\ {}
"python.linting.banditEnabled": verdadero,
"python.linting.banditArgs":
"--severity-level", "medium",
"--nivel de confianza", "medio"
]
"python.linting.enabled": verdadero
{\cHFF}
PyCharm Integration¶
# Configuración de la herramienta externa
# Programa: bandido
# Argumentos: -r $FileDir$ -f json
# Directorio de trabajo: $ProjectFileDir$
Vim/Neovim Integration¶
" .vimrc o init.vim
" Integración bandidal con ALE
g:ale_linters = \{
\ 'python': ['bandit', 'flake8', 'pylint'],
\ '
g:ale_python_bandit_options = '-ll -ii '
Best Practices¶
Configuration Management¶
# .bandit - Configuración integral
'B40', 'B40'
skips: ['B101'] # Skip assert_used in test files
exclude_dirs: [
'*/tests/*,
'*/test/*',
'*/.venv/*,
'*/venv/*,
'*/.env/*,
'*/env/*,
'*/migrations/*,
'*/node_modules/*,
'*/.git/*
]
# Severidad: LOW, MEDIUM, ALTO
gravedad: MEDIO
# Confianza: LOW, MEDIUM, ALTO
confianza: MEDIO
False Positive Management¶
# Comentarios en línea para suprimir las advertencias
contraseña = "default" # nosec B105
# Prueba específica de Suppress
subprocesos de importación
subprocess.call(shell_command, shell=True) # nosec B602
# Suppress múltiples pruebas
eval(user_input) # nosec B307,B102
Team Workflow Integration¶
# Pre-commit configuración (.pre-commit-config.yaml)
repos:
- repo: __URL_0_
rev: '1.7.5'
ganchos:
- id: bandit
args: ['-ll', '-ii']
excluir: ^tests/
# Hacer la integración de archivos
. PHONY: seguridad-escan
de seguridad:
bandit -r . -ll -ii -f json -o security-report.json
@echo "Security scan completed. Compruebe los resultados de seguridad-report.json."
. PHONY: control de seguridad
Control de seguridad:
bandido -r. -ll -ii
@if [ $? -ne 0 ]; entonces \
eco "Problemas de seguridad encontrados. Por favor revise y corrija."; \
salida 1; \
fi
__CODE_BLOCK_32_bash
# Edición: ImportError cuando se ejecuta Bandit
# Solución: Asegurar un entorno de pitón adecuado
python -m pip install --upgrade bandit
# Edición: No se lee la configuración
# Solución: Verificar la ubicación del archivo de configuración y sintaxis
bandido - ¡Ayuda!
# Número: Demasiados falsos positivos
# Solución: Configuración y supresiones de uso
bandido -r. --skip B101,B601 -ll -ii
# Edición: Problemas de rendimiento con grandes bases de código
# Solución: Excluir directorios innecesarios
bandit -r . --exclude "*/venv/*,*/node_modules/*,*/.git/*
# Edición: Integración con fallos CI/CD
# Solución: Use códigos de salida apropiados y manejo de errores
bandit -r . -ll -ii # Continúa con los errores
Performance Optimization¶
# Procesamiento paralelo (si está disponible)
bandido -r. - Procesos 4
# Excluir grandes directorios
bandit -r . --exclude "*/venv/*,*/env/*,*/node_modules/*,*/.git/*,*/migrations/*
# Use pruebas específicas sólo
bandido -r. --tests B201,B301,B401,B501
# Profundidad de recursión
encontrar . -nombre "*.py" -no -pate "*/venv/*"
Debugging¶
# Producción de verbos
bandido -v -r .
# Modo de depuración
bandido -d -r.
# Mostrar archivos saltados
bandido -r. --verbose
# Prueba archivo específico con todos los detalles
bandit -v -ll -iii specific_file.py
Resources¶
- Bandit Official Documentation
- Bandit GitHub Repository
- Python Security Best Practices
- OWASP Python Security
- PyCQA Tools
This cheat sheet provides comprehensive guidance for using Bandit to identify security vulnerabilities in Python code. Always combine static analysis with other security testing methods for comprehensive coverage.
|xargs bandit -ll -ii
GitLab CI¶
Jenkins Pipeline¶
Azure DevOps¶
Common Vulnerability Patterns¶
Hardcoded Passwords (B105, B106, B107)¶
SQL Injection (B608)¶
Command Injection (B602, B605, B606, B607)¶
Insecure Random (B311)¶
Unsafe YAML Loading (B506)¶
Custom Rules and Plugins¶
Creating Custom Tests¶
Plugin Development¶
Using Custom Tests¶
Automation and Scripting¶
Automated Scanning Script¶
Batch Processing Script¶
Integration with IDEs¶
VS Code Integration¶
PyCharm Integration¶
Vim/Neovim Integration¶
Best Practices¶
Configuration Management¶
False Positive Management¶
Team Workflow Integration¶
Troubleshooting¶
Common Issues¶
Performance Optimization¶
Debugging¶
Resources¶
- Bandit Official Documentation
- Bandit GitHub Repository
- Python Security Best Practices
- OWASP Python Security
- PyCQA Tools
This cheat sheet provides comprehensive guidance for using Bandit to identify security vulnerabilities in Python code. Always combine static analysis with other security testing methods for comprehensive coverage.
|xargs bandit -ll -ii ```
Recursos¶
- Documentación Oficial del Banco
- Bandit GitHub Repository
- Python Security Best Practices
- OWASP Python Security
- PyCQA Tools
-...
*Esta hoja de trampa proporciona una guía completa para usar Bandit para identificar vulnerabilidades de seguridad en el código Python. Combina siempre el análisis estático con otros métodos de pruebas de seguridad para una cobertura integral. *