Vai al contenuto

Bandit Python Security Linter Cheat Sheet

Traduzione: Copia tutti i comandi Traduzione: Generare PDF < > ## Panoramica 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. ## Installazione ### Utilizzo di pip Traduzione: ### Utilizzo di conda Traduzione: ### Utilizzo dei gestori dei pacchetti Traduzione: ### Installazione Docker Traduzione: ## Uso di base ### Scansioni semplici Traduzione: ### Formati di uscita Traduzione: ### Filtro della gravità e della fiducia Traduzione: ## Configurazione ### File di configurazione (.bandit) Traduzione: ### pyproject.toml Configurazione Traduzione: ### Configurazione della riga di comando Traduzione: ## Uso avanzato ### Selezione test personalizzata Traduzione: ### Baseline e scansione progressiva Traduzione: ### Integrazione con Git Traduzione: # .github/flusso di lavoro/security.yml nome: Scansione di sicurezza su: lavori: bandit: run-on: ubuntu-latest passi: - utilizza: 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: # .gitlab-ci.yml 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: # azure-pipelines.yml 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 ' - attività: PublishTestResults@2 ingressi: testRisultatiFiles: '$(Agent.TempDirectory)/bandit-report.json ' test di prova RunTitle: 'Bandit Security Scan ' Traduzione: # BAD: password codificata password = "secret123" api_key = "abc123def456" # GOOD: variabili ambientali importazione password = os.environ.get('PASSWORD') api_key = os.environ.get('API_KEY') # GOOD: File di configurazione import configparser config = configparser.ConfigParser() config.read('config.ini') password = config.get('database', 'password') Traduzione: # BAD: formattazione della stringa query = "SELECT * DAgli utenti DOVE id = %" % user_id query = f"SELECT * DAgli utenti DOVE id = \\{user_id\\\}" # GOOD: Domande parametrizzate cursor.execute("SELECT * DAgli utenti DOVE id = %", (user_id,)) cursor.execute("SELECT * DAgli utenti DOVE id = ?", (user_id,) Traduzione: # BAD: iniezione conchiglia importazione os.system(f)ls \\{user_input\\\} os.popen(f)grep \\{pattern\\\} \\{filename\\} # GOOD: Sottoprocesso con lista importazione subprocesso subprocess.run(['ls', user_input]) subprocess.run(['grep', pattern, filename]) Traduzione: # BAD: casuale prevedibile importazione casuale token = random.randint(1000, 9999) # GOOD: Crittograficamente sicuro segreti di importazione token = secrets.randbelow(9999) safe_token = secrets.token_hex(16) Traduzione: # BAD: carico non sicuro YAML importazione yaml dati = yaml.load (user_input) # GOOD: caricamento sicuro YAML dati = yaml.safe_load (user_input) dati = yaml.load (user_input, Loader=yaml.SafeLoader) Traduzione: # custom_bandit_test.py 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: # bandit_plugin.py dal bandito. estensione dell'importazione del nucleo_loader def load_tests(): ""Prove personalizzate"" [custom_security_check] # Registrare plugin estensione_loader.MANAGER.register_plugin('custom_tests', load_tests) Traduzione: # Carica test personalizzati bandit -r. --tests custom_bandit_test.py # Utilizzare il plugin bandito -r. --plugin bandit_plugin.py Traduzione: #!/usr/bin/env python3 # bandit_scanner.py 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") # Exit with error code if high severity issues found se il riassunto ['high_severity'] > `` 0: stampa("I problemi di gravità trovati!") sys.exit(1) Altro: stampa("Scan ha fallito!" sys.exit(1) # '_main__': principale() Traduzione: #!/bin/bash # lot_bandit_scan.sh # Configurazione PROJECTS_DIR="/path/to/projects" RELAZIONI_DIR="/percorso/riportazioni" Traduzione: +% Y%m%d_%H%M%S) # Crea la directory dei report mkdir -p "$REPORTS_DIR" # Funzione per la scansione del progetto ) 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..." # 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 | 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" # # Scansione di tutti i progetti Python 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: # Configurazione degli strumenti esterni # Programma: bandit # Argomenti: -r $FileDir$ -f json # directory di lavoro: $ProjectFileDir$ Traduzione: .vimrc o init.vim " Integrazione Bandit con ALE g:ale_linters = ['bandit', 'flake8', 'pylint'], # let g:ale_python_bandit_options = '-ll -ii ' Traduzione: # .bandit - Configurazione completa B30, B305, B30 skips: ['B101'] # Salta assert_used in file di test escludere_dirs: [ */test/*, */test/*, */.venv/*, */venv/*, */.env/*, */env/*, */migrazioni/*, */node_modules/*, */.git/* ] # Punti positivi: LOW, MEDIUM, HIGH gravità: MEDIUM # Confidenza: LOW, MEDIUM, HIGH fiducia: MEDIUM Traduzione: # Osservazioni in linea per sopprimere gli avvisi password = "default" # nosec B105 # Suppress test specifico importazione subprocesso subprocess.call(shell_command, shell=True) # nosec B602 # Supprimere più test eval(user_input) # Nosec B307, B102 # Traduzione: # Configurazione pre-commit (.pre-commit-config.yaml) repos: - Repo: 1,7.5. ganci: - id: bandit ['-ll', '-ii'] escludere: # Rendere l'integrazione dei file . 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: # Problema: ImportError quando si esegue Bandit # Soluzione: Assicurare un ambiente Python corretto python -m pip install --upgrade bandit # Problema: la configurazione non viene letta # Soluzione: Verificare la posizione del file di configurazione e la sintassi bandito --help-config # Problema: Troppi falsi positivi # Soluzione: Configurazione dei sintoni e soppressione dell'uso bandito - B101, B601 -ll -iii # Problema: problemi di prestazioni con grandi codebases # Soluzione: Escludere directory inutili bandit -r. --escluso "*/venv/*,*/node_modules/*,*/.git/*" # Problema: Integrazione con CI/CD guasto # Soluzione: Utilizzare i codici di uscita appropriati e la gestione degli errori | bandit -r. -ll -ii | | true # Continua sugli errori | Traduzione: # Lavorazione parallela (se disponibile) bandit -r. --processi 4 # Escludere grandi directory */venv/*,*/env/*,*/node_modules/*,*/.git/*,*/migrazioni/* # Utilizzare solo prove specifiche bandit -r. --test B201, B301, B401, B501 # Limitare la profondità di ricorsione | -name "*.py" -not -path "*/venv/*" | head -100 | xargs bandit | Traduzione: # Uscita Verbose bandit -v -r. # Modalità Debug bandit -d -r. # Mostra i file saltati bandit -r. --verbose # Test di file specifici con tutti i dettagli bandit -v -ll -iii specific_file.py Traduzione: ## Integrazione CI/CD ### GitHub Azioni Traduzione: ### GitLab CI Traduzione: ### Jenkins Pipeline Traduzione: ### Azure DevOps Traduzione: ## Vulnerabilità comune Modelli ### Password con codice rigido (B105, B106, B107) Traduzione: ### SQL Injection (B608) Traduzione: ### Iniezione di comando (B602, B605, B606, B607) Traduzione: ### Insicuro Random (B311) Traduzione: ### Caricamento non sicuro YAML (B506) Traduzione: ## Regole e Plugin personalizzati ### Creazione di test personalizzati Traduzione: ### Sviluppo del plugin Traduzione: ### Utilizzo di test personalizzati Traduzione: ## Automazione e scrittura ### Script di scansione automatizzato Traduzione: ### script di elaborazione batch Traduzione: ## Integrazione con IDE ### Integrazione del codice VS Traduzione: ### Integrazione PyCharm Traduzione: ### Integrazione Vim/Neovim Traduzione: ## Migliori Pratiche ### Gestione della configurazione Traduzione: ### Falsa gestione positiva Traduzione: ### Integrazione del flusso di lavoro del team Traduzione: ## Risoluzione dei problemi ### Questioni comuni Traduzione: ### Ottimizzazione delle prestazioni # ### Debug Traduzione: ## Risorse - [Bandit Documentazione ufficiale](__LINK_6__] -%20[Bandit%20GitHub%20Repository](__LINK_6__) - [Python Security Best Practices](__LINK_6__) - [OWASP Python Security](__LINK_6__] -%20[PyCQA%20Tools](__LINK_6__) --- *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. *