FRONTMATTER_48_# Bandit Python Security Linter Cheat Sheet¶
Traduzione:
Traduzione:
Bandit è un linter di sicurezza progettato per trovare problemi di sicurezza comuni in codice Python. Analizza il codice sorgente Python e identifica le potenziali vulnerabilità di sicurezza attraverso la scansione di modelli noti e anti-patterns. Bandit è ampiamente usato nelle tubazioni DevSecOps per catturare i problemi di sicurezza presto nel processo di sviluppo, rendendolo uno strumento essenziale per lo sviluppo sicuro di Python.
Nota: Bandit è progettato per identificare potenziali problemi di sicurezza e dovrebbe essere utilizzato come parte di una strategia di test di sicurezza completa. Può produrre falsi positivi e dovrebbe essere combinato con altri metodi di test di sicurezza.
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Baseline e scansione progressiva Traduzione:
Traduzione:
nome: Scansione di sicurezza
su:
lavori: bandit: run-on: ubuntu-latest passi: - usi: azioni/checkout@v3
nome: Impostare Python utilizza: azioni/setup-python@v4 con: python-version: 3.9.
nome: Installa Bandit run: pip install bandit[toml]
nome: Run Bandit run: bandit -r. -f json -o bandit-report.json
nome: Risultati di caricamento utilizza: azioni/upload-artifact@v3 con: nome: bandit-report percorso: bandit-report.json
nome: Bandit Report usi: tj-actions/bandit@v5.1 con: opzioni: "-r. -f json" uscita_zero: vero Traduzione:
fasi: - Sicurezza
bandit: stadio: sicurezza immagine: pitone:3.9 prima_script: - pip install bandit[toml] script: - bandit -r. -f json -o bandit-report.json artefatti: relazioni: sast: bandit-report.json percorsi: - bandit-report.json scaduto: 1 settimana consent_failure: vero Traduzione: // Jenkinsfile pipeline \ {} agente
fasi {} stadio('Scansione della sicurezza') \ {} Passi Traduzione: sh 'pip install bandit[toml] ' sh 'bandit -r. -f json -o bandit-report.json '
Traduzione: {} sempre. {} artefatti: 'bandit-report.json', impronta digitale: true pubblicareHTML([ consentire Mancante: falso, sempreLinkToLastBuild: vero, tenere tutto: vero, relazione Dir: '. reportFiles: 'bandit-report.html', reportName: "Bandit Security Report ' ]
Traduzione:
trigger: - principale
piscina: vmImage: 'ubuntu-latest '
passi: - task: UsePythonVersion@0 ingressi: versione Spec: '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 ingressi: testRisultatiFiles: '$(Agent.TempDirectory)/bandit-report.json ' test di prova RunTitle: 'Bandit Security Scan ' Traduzione:
password = "secret123" api_key = "abc123def456"
importazione password = os.environ.get('PASSWORD') api_key = os.environ.get('API_KEY')
import configparser config = configparser.ConfigParser() config.read('config.ini') password = config.get('database', 'password') Traduzione:
query = "SELECT * DAgli utenti DOVE id = %" % user_id query = f"SELECT * DAgli utenti DOVE id = \{user_id\}"
cursor.execute("SELECT * DAgli utenti DOVE id = %", (user_id,)) cursor.execute("SELECT * DAgli utenti DOVE id = ?", (user_id,) Traduzione:
importazione os.system(f)ls \{user_input\} os.popen(f)grep \{pattern\} \{filename\}
importazione subprocesso subprocess.run(['ls', user_input]) subprocess.run(['grep', pattern, filename]) Traduzione:
importazione casuale token = random.randint(1000, 9999)
segreti di importazione token = secrets.randbelow(9999) safe_token = secrets.token_hex(16) Traduzione:
importazione yaml dati = yaml.load (user_input)
dati = yaml.safe_load (user_input) dati = yaml.load (user_input, Loader=yaml.SafeLoader) Traduzione:
import bandit dal bandito. core import test_properties
@test_properties.test_id('B999') @test_properties.checks('Call') def custom_security_check(context): """Check for custom security pattern"" se context.call_function_name_qual == 'dangerous_function': ritorno bandito. Fascicolo severity=bandit. Grandioso. fiducia=bandit. Grandioso. testo="Usa di pericolosa_funzione rilevata", lineno=context.node.lineno,
Traduzione:
dal bandito. estensione dell'importazione del nucleo_loader
def load_tests(): ""Prove personalizzate"" [custom_security_check]
estensione_loader.MANAGER.register_plugin('custom_tests', load_tests) Traduzione:
bandit -r. --tests custom_bandit_test.py
bandito -r. --plugin bandit_plugin.py Traduzione:
importazione subprocesso importazione json import sys import argparse da pathlib import Sentiero
classe BanditScanner: def init(self, project_path, config_file=Noe): self.project_path = Path(project_path) self.config_file = config_file auto.risultati = \{}
def run_scan(self, output_format='json', severity='MEDIUM', trust='MEDIUM'): ""Run Bandit scansione con parametri specificati""" cmd = 'bandit', '-r', str(self.project_path), '-f', output_format, f'-l{self._severity_to_flag(severity)\}, f'-i{self._confidence_to_flag(confidence)\} ' ]
se self.config_file: cmd.extend(['--configfile', self.config_file])
prova: risultato = subprocess.run(cmd, catch_output=True, text=True, check=False)
se output_format == 'json': self.results = json.loads(result.stdout) se risultato. Esclusivamente Altro: self.results = risultato.stdout
restituire il risultato.returncode == 0
eccetto sottoprocesso. ChiamatoProcess Errore come: stampa(f"Error in esecuzione Bandit: \{e\}") ritorno Falso tranne json. JSONDecode Errore come: stampa(f"Error parsing JSON output: \{e}") ritorno Falso
def _severity_to_flag(self, severity): ""Converti la gravità alla Bandit flag"" mapping = \{'LOW': '', 'MEDIUM': 'l', 'HIGH': 'll'} rimbalzare. ottenere(severity.upper(), 'l')
def _confidence_to_flag(self, trust): ""Convertire la fiducia nella bandiera Bandit"" mapping = \{'LOW': 'ii', 'MEDIUM': 'i', 'HIGH': '\} ritorno mapping.get (confidence.upper(), 'i')
def get_summary(self): ""Riepilogo della scansione"" se non èinstanza(autorisultati, ditta): ritorno "Nessun risultato disponibile"
metriche = self.results.get('metrics', \{}) Restituzione 'total_lines': metrics.get('_totals', \\}).get('loc', 0), 'total_issues': len(self.results.get('results', []), 'high_severity': len([r per r in self.results.get('results', []) se r.get('problem_severity') == 'HIGH']), 'medium_severity': len([r per r in self.results.get('results', []) se r.get('problem_severity') == 'MEDIUM']), 'low_severity': len([r per r in self.results.get('results', []) se r.get('problem_severity') == 'LOW')
def get_issues_by_severity(self, severity='HIGH'): """I problemi della gravità"" se non èinstanza(autorisultati, ditta): []
[problema per emissione in self.results.get('results', []) se issue.get('issue_severity') == severity.upper()
def generare_report(self, output_file='bandit_report.html'): ""Generate HTML report"" cmd = 'bandit', '-r', str(self.project_path), '-f', 'html', '-o', output_file ]
se self.config_file: cmd.extend(['--configfile', self.config_file])
prova: sottoprocess.run(cmd, check=True) Ritorno Vero eccetto sottoprocesso. ChiamatoProcess Errore: ritorno Falso
def save_results(self, output_file='bandit_results.json'): ""Salva risultati a file"" se isinstance(self.results, dict): con aperto (output_file, 'w') come f: json.dump(self.results, f, indent=2) Altro: con aperto (output_file, 'w') come f: f.write(str(self.results)))
def principale(): parser = argparse. ArgumentParser(descrizione='Automated Bandit Scanner') parser.add_argument('project_path', help='Path to project to scan') parser.add_argument('--config', help='Bandit file di configurazione') parser.add_argument('--severity', default='MEDIUM', Traduzione: help='Minimum severity level') parser.add_argument('--confidence', default='MEDIUM', Traduzione: help='Minimo livello di fiducia') parser.add_argument('--output', help='Output file for results') parser.add_argument('--report', help='Generate HTML report')
args = parser.parse_args()
scanner = BanditScanner (args.project_path, args.config)
stampa(f)Scanning \{args.project_path\}... successo = scanner.run_scan(severity=args.severity, trust=args.confidence)
se il successo: sommario = scanner.get_summary() stampa(f"Scan completato con successo!") print(f)Total lines of code: \{summary['total_lines']}") stampa(f) Problemi totali trovati: \{summary['total_issues']}") stampa(f"High severity: \{summary['high_severity']}") stampa(f) gravità media: \{summary['medium_severity']}] stampa(f)Low severity: \{summary['low_severity']}]
Se args. uscita: scanner.save_results(args.output) stampa(f"Risultati salvati su \{args.output\}
se args.report: se scanner.generate_report(args.report): stampa(f"HTML report generato: \{args.report\}") Altro: print("Failed per generare report HTML")
se il riassunto ['high_severity'] > `` 0: stampa("I problemi di gravità trovati!") sys.exit(1) Altro: stampa("Scan ha fallito!" sys.exit(1)
principale() Traduzione:
PROJECTS_DIR="/path/to/projects" RELAZIONI_DIR="/percorso/riportazioni" Traduzione: +% Y%m%d_%H%M%S)
mkdir -p "$REPORTS_DIR"
) progetto locale_path="\(1" progetto locale_name=\)(basename "\(project_path") report_file="\)REPORTS_DIR/\(\{project_name\}_\){DATE}.json" html_report="$ RELAZIONI_DIR/\(\{project_name\}_\){DATE}.html
echo "Scanning $project_name..."
bandit -r "\(project_path" -f json -o "\)report_file" -ll -ii bandit -r "\(project_path" -f html -o "\)html_report" -ll -ii
high_issues=\((jq '.results|map(select(.issue_severity == "HIGH"))|length" "\)report_file")
se ["$high_issues" -gt 0 ]; allora echo "WARNING: \(project_name ha \(high_issues ad alta gravità problemi!" echo "\)project_name" > "\)REPORTS_DIR/high_severity_projects.txt"
echo "Scan completato per $project_name"
trovare "\(PROJECTS_DIR" -name "*.py" -type f|while read -r file; do project_dir=\)(dirname "\(file") se [! -f "\)project_dir/.bandit_scanned" ]; allora scan_project "\(project_dir" toccare "\)project_dir/.bandit_scanned"
Fatto
eco "Batch scansione completata. Rapporti salvati a $REPORTS_DIR" Traduzione: // .vscode/settings.json . {} "python.linting.banditEnabled": vero, "python.linting.banditArgs": [ "--severity-level", "medium", "-livello di fiducia", "medium" ] "python.linting.enabled": vero
Traduzione:
Traduzione: .vimrc o init.vim " Integrazione Bandit con ALE g:ale_linters = ['bandit', 'flake8', 'pylint'],
let g:ale_python_bandit_options = '-ll -ii ' Traduzione:
B30, B305, B30
skips: ['B101'] # Salta assert_used in file di test
escludere_dirs: [ /test/, /test/, /.venv/, /venv/, /.env/, /env/, /migrazioni/, /node_modules/, /.git/ ]
gravità: MEDIUM
fiducia: MEDIUM Traduzione:
password = "default" # nosec B105
importazione subprocesso subprocess.call(shell_command, shell=True) # nosec B602
eval(user_input) # Nosec B307, B102 # Traduzione:
repos: - Repo: 1,7.5. ganci: - id: bandit ['-ll', '-ii'] escludere:
. PHONY: sicurezza-scan sicurezza-scan: bandit -r. -ll -iii -f json -o security-report.json @echo "Security scan completato. Controllare la sicurezza-report.json per i risultati."
. PHONY: controllo di sicurezza controllo di sicurezza: bandit -r. -ll -ii @if [ $? echo "I problemi di sicurezza trovati. Si prega di rivedere e correggere."; . uscita 1; \
Traduzione:
python -m pip install --upgrade bandit
bandito --help-config
bandito - B101, B601 -ll -iii
bandit -r. --escluso "/venv/,/node_modules/,/.git/"
bandit -r. -ll -ii||true # Continua sugli errori Traduzione:
bandit -r. --processi 4
/venv/,/env/,/node_modules/,/.git/,/migrazioni/
bandit -r. --test B201, B301, B401, B501
-name ".py" -not -path "/venv/*"|head -100|xargs bandit Traduzione:
bandit -v -r.
bandit -d -r.
bandit -r. --verbose
bandit -v -ll -iii specific_file.py Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
Traduzione:
*Questo foglio di scacchi fornisce una guida completa per l'utilizzo di Bandit per identificare le vulnerabilità di sicurezza nel codice Python. Combina sempre l'analisi statica con altri metodi di test di sicurezza per una copertura completa. *