DEV Community

JEFFERSON ROSAS CHAMBILLA
JEFFERSON ROSAS CHAMBILLA

Posted on

Applying Bandit SAST Tool to Secure Python Applications

Why Bandit for Python Security?

Bandit is an open-source SAST tool developed by the OpenStack Security Project that specializes in analyzing Python code for common security issues. It's particularly valuable because:

  • Python-specific analysis - Understands Python idioms and common patterns
  • Plugin-based architecture - Extensible with custom checks
  • CI/CD friendly - Designed for automation
  • Zero cost - Completely free and open-source

Common Vulnerabilities Bandit Detects

  • SQL injection vulnerabilities
  • Shell injection risks
  • Hardcoded passwords and secrets
  • Use of insecure modules
  • Input validation issues
  • Information disclosure risks

Hands-On: Implementing Bandit

Installation

# Install using pip pip install bandit # Or install from source git clone https://github.com/PyCQA/bandit.git cd bandit pip install . 
Enter fullscreen mode Exit fullscreen mode

Basic Usage

# Scan a single file bandit my_script.py # Scan an entire directory bandit -r my_project/ # Generate HTML report bandit -r my_project/ -f html -o report.html # Scan with specific security level bandit -r my_project/ -l high 
Enter fullscreen mode Exit fullscreen mode

Sample Vulnerable Python Code

# vulnerable_app.py import os import pickle import subprocess import sqlite3 def process_user_input(): # Vulnerability: Code injection  user_input = input("Enter command: ") os.system(user_input) # B602: subprocess_popen_with_shell_equals_true  def database_operations(): # Vulnerability: SQL injection  username = input("Enter username: ") conn = sqlite3.connect('users.db') cursor = conn.cursor() cursor.execute(f"SELECT * FROM users WHERE username = '{username}'") # B608: hardcoded_sql_expressions  def data_deserialization(): # Vulnerability: Insecure deserialization  data = input("Enter serialized data: ") obj = pickle.loads(data.encode()) # B301: blacklist 
Enter fullscreen mode Exit fullscreen mode

Running Bandit Scan

bandit -r vulnerable_app.py -f txt 
Enter fullscreen mode Exit fullscreen mode

Sample Bandit Output

Results generated: >> Issue: [B602:subprocess_popen_with_shell_equals_true] Using subprocess with shell=True Severity: High Confidence: High Location: vulnerable_app.py:8 More Info: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b602-subprocess-popen-with-shell-equals-true 7 user_input = input("Enter command: ") 8 os.system(user_input) >> Issue: [B608:hardcoded_sql_expressions] Possible SQL injection vector through string-based query construction. Severity: Medium Confidence: Medium Location: vulnerable_app.py:15 15 cursor.execute(f"SELECT * FROM users WHERE username = '{username}'") >> Issue: [B301:blacklist] Use of unsafe deserialization function. Severity: High Confidence: High Location: vulnerable_app.py:20 20 obj = pickle.loads(data.encode()) 
Enter fullscreen mode Exit fullscreen mode

Advanced Bandit Configuration

Custom Configuration File

# bandit.yml exclude_dirs: ['tests', 'venv', 'migrations'] skips: ['B101', 'B102'] tests: ['B301', 'B302', 'B601', 'B602'] targets: - src/ - app/ output_format: json verbose: true 
Enter fullscreen mode Exit fullscreen mode

Using Configuration File

bandit -c bandit.yml -r my_project/ 
Enter fullscreen mode Exit fullscreen mode

CI/CD Integration (GitHub Actions)

name: Security Scan with Bandit on: [push, pull_request] jobs: security-scan: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.9' - name: Install Bandit run: pip install bandit - name: Run Bandit Security Scan run: bandit -r . -f json -o bandit-report.json - name: Upload Bandit Report uses: actions/upload-artifact@v3 with: name: bandit-report path: bandit-report.json 
Enter fullscreen mode Exit fullscreen mode

Bandit Test Types and Severity Levels

Severity Levels

  • Low: Code quality issues, minor security concerns
  • Medium: Potential security vulnerabilities
  • High: Critical security vulnerabilities

Common Test IDs

  • B1xx: Various general tests
  • B2xx: Application/framework-specific issues
  • B3xx: Blacklisted imports and functions
  • B4xx: Using insecure random generators
  • B5xx: SSL/TLS issues
  • B6xx: Shell injection vulnerabilities
  • B7xx: Pickle and YAML deserialization

Custom Bandit Plugins

Creating Custom Tests

# custom_checks.py import bandit from bandit.core import test_properties as test @test.checks('Call') @test.test_id('B901') def hardcoded_api_key(context): """Check for hardcoded API keys""" suspicious_strings = ['api_key', 'secret_key', 'password'] if context.call_function_name_qual in suspicious_strings: return bandit.Issue( severity=bandit.HIGH, confidence=bandit.MEDIUM, text="Potential hardcoded API key detected" ) 
Enter fullscreen mode Exit fullscreen mode

Using Custom Plugins

bandit -r my_project/ -p custom_checks.py 
Enter fullscreen mode Exit fullscreen mode

Best Practices for Bandit Implementation

1. Integrate Early in Development

# Pre-commit hook example # .git/hooks/pre-commit #!/bin/bash bandit -r . -l high -i 
Enter fullscreen mode Exit fullscreen mode

2. Regular Scheduled Scans

# GitHub Actions scheduled scan on: schedule: - cron: '0 2 * * 1' # Weekly scan 
Enter fullscreen mode Exit fullscreen mode

3. Baseline Establishment

# Establish baseline ignoring existing issues bandit -r . --baseline baseline.json 
Enter fullscreen mode Exit fullscreen mode

4. Quality Gates

# Fail build on high severity issues bandit -r . -l high --exit-zero 
Enter fullscreen mode Exit fullscreen mode

Limitations and Considerations

While Bandit is powerful, it's important to understand its limitations:

  • Static analysis only - Cannot detect runtime issues
  • Python-specific - Only works with Python code
  • Pattern-based - May produce false positives/negatives
  • No data flow analysis - Limited context awareness

Conclusion

Bandit provides an excellent open-source SAST solution for Python applications. Its ease of use, comprehensive vulnerability detection, and seamless CI/CD integration make it an essential tool for any Python developer concerned with security.

By implementing Bandit in your development workflow, you can catch common security issues early, reduce remediation costs, and build more secure Python applications.

Top comments (0)