DEV Community

Automating Security in Python: A Hands-On Guide to SAST with Bandit and GitHub Actions

Introduction

In today's fast-paced development cycles, security can no longer be an afterthought. Static Application Security Testing (SAST) tools help developers catch vulnerabilities early by analyzing source code before it is compiled or deployed to production.

In this article, we will explore how to apply a SAST tool to a Python application. While tools like SonarQube or Snyk are popular, we will focus on Bandit, a powerful and lightweight tool designed specifically to find common security issues in Python code.

What is Bandit?

Bandit is an open-source SAST tool maintained by the Python Packaging Authority (PyPA). It parses Python code, builds an Abstract Syntax Tree (AST), and runs appropriate plugins against the AST nodes to detect security flaws like hardcoded passwords, injection vulnerabilities, and unsafe library usage.

The Demo Application

Let's create a simple Python application that intentionally contains some security vulnerabilities for Bandit to find. We'll simulate a basic script that has hardcoded credentials and uses dangerous functions.

Here is our app.py:

import subprocess
import yaml

# VULNERABILITY 1: Hardcoded credentials
DB_PASSWORD = "super_secret_password_123"

def run_command(user_input):
    # VULNERABILITY 2: Command injection risk (shell=True)
    print("Executing command...")
    subprocess.call(user_input, shell=True)

def parse_config(yaml_data):
    # VULNERABILITY 3: Unsafe YAML loading
    config = yaml.load(yaml_data)
    return config

if __name__ == "__main__":
    print("App started.")
    run_command("ls -la")
Enter fullscreen mode Exit fullscreen mode

Running Bandit Locally

To test our code locally, we first install Bandit via pip:

pip install bandit
Enter fullscreen mode Exit fullscreen mode

Then, we can run it against our app.py file:

bandit -r app.py
Enter fullscreen mode Exit fullscreen mode

Bandit will immediately flag the issues we planted:

  1. B105: hardcoded_password_string - Flags the hardcoded DB_PASSWORD.
  2. B602: subprocess_popen_with_shell_equals_true - Warns about the potential command injection in subprocess.call.
  3. B506: yaml_load - Warns about using the unsafe yaml.load function instead of yaml.safe_load.

Automating SAST with GitHub Actions

Running tools locally is great, but enforcing them automatically on every push is the best practice. Let's set up a GitHub Action to automatically run Bandit whenever code is pushed to our repository.

Create a file in your repository at .github/workflows/bandit.yml:

name: Bandit SAST Scan

on:
  push:
    branches: [ "main" ]

jobs:
  security-scan:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.10'

    - name: Install dependencies
      run: pip install bandit

    - name: Run Bandit
      run: bandit -r . -f txt -o bandit-report.txt || true

    - name: Upload Bandit Report
      uses: actions/upload-artifact@v4
      with:
        name: bandit-security-report
        path: bandit-report.txt
Enter fullscreen mode Exit fullscreen mode

How this automation works:

  • Triggers: The action runs on every push to the main branch.
  • Execution: It installs Bandit and runs it across the entire repository (-r .).
  • Artifacts: It generates a report and uploads it as an artifact, so developers can download and review the findings directly from the GitHub Actions tab. (Note: We use || true to prevent the workflow from failing immediately so the report can be uploaded).

Conclusion

Integrating a SAST tool like Bandit into your Python projects is a straightforward process that significantly enhances your code's security posture. By automating this process with GitHub Actions, you ensure that vulnerabilities are caught in the CI/CD pipeline before they ever reach production.


🔗 Check out the full demo code and automated GitHub Action in this repository:
https://github.com/Cristhian465/Trabajo-en-equipo-de-investigaci-n-N-01-Herramientas-Sast-para-aplicaciones

Top comments (0)