Bandit: Инструмент для Поиска Уязвимостей в Python-коде

Bandit: Инструмент для Поиска Уязвимостей в Python-коде


Bandit: Инструмент для Поиска Уязвимостей в Python-коде


Введение

Bandit — это мощный инструмент статического анализа кода, созданный специально для Python. Его цель — автоматическое выявление уязвимостей безопасности в исходном коде, таких как инъекции, XSS, использование небезопасных функций и конфиденциальных данных. Разработанный в рамках проекта OpenStack, Bandit стал стандартом де-факто для аудита безопасности Python-приложений. В эпоху, когда уязвимости в ПО приводят к катастрофическим последствиям, инструменты вроде Bandit критически важны для DevSecOps.


Как Работает Bandit

Bandit анализирует абстрактное синтаксическое дерево (AST) Python-кода, что позволяет ему:

  • Обходить ограничения динамического анализа (например, зашифрованные строки или сложные импорты).
  • Проверять код без его выполнения, минимизируя риски.
  • Использовать набор правил (плагинов) для поиска шаблонов, связанных с уязвимостями.

Пример логики проверки:

# Проблемный код
import subprocess
subprocess.call(user_input)  # Риск комманд-инъекции!

# Bandit обнаружит:
# [B602: subprocess_popen_with_shell_equals_true]

Установка и Настройка

Установка через pip:

pip install bandit

Базовое использование:

bandit -r /path/to/your/code  # Рекурсивная проверка директории

Ключевые параметры:

  • -l: Список всех доступных тестов.
  • -f: Формат отчёта (txt, json, html).
  • -c: Конфигурационный файл для кастомизации.
  • --skip: Игнорировать тесты (например, B101,B102).

Примеры Обнаружения Уязвимостей

  1. Хардкодированный пароль:

    password = "admin123"  # Bandit: B105

    Риск: Утечка учетных данных.
    Решение: Использовать переменные окружения.

  2. SQL-инъекция:

    query = "SELECT * FROM users WHERE id = " + user_input  # Bandit: B608

    Риск: Компрометация БД.
    Решение: Перейти на ORM или параметризованные запросы.

  3. Небезопасные десериализаторы:

    import pickle
    data = pickle.load(untrusted_input)  # Bandit: B301

    Риск: RCE-атака.
    Решение: Использовать json или безопасные сериализаторы.


Интеграция в CI/CD

Пример для GitHub Actions:

name: Security Scan
on: [push]
jobs:
  bandit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Bandit
        run: |
          pip install bandit
          bandit -r src/ -f html -o report.html

Почему это важно:

  • Автоматическая блокировка небезопасного кода в PR.
  • Соответствие стандартам SOC2, ISO 27001.

Расширение Функциональности

  1. Кастомизация правил:
    Создайте .bandit.yml для управления проверками:

    skips: [B201]  # Игнорировать тест на assert
    tests:
      - id: B101
        severity: HIGH   # Изменить важность
  2. Свои плагины:
    Напишите модуль в Python:

    from bandit.core import test_properties as test
    
    @test.test_id("CUSTOM-001")
    @test.checks("Call")
    def forbid_http_requests(context):
        if "requests.get" in context.call_function_name:
            return bandit.Issue(severity=bandit.HIGH)

Ограничения Bandit

  • Ложные срабатывания: Иногда ругается на безопасный код (например, assert в тестах).
  • Динамический код: Не анализирует поведение во время выполнения.
  • Контекст: Не учитывает бизнес-логику рисков.
    Рекомендация: Комбинируйте с динамическими анализаторами (OWASP ZAP) и ручным аудитом.

Альтернативы

  • Safety: Проверка зависимостей на известные CVE.
  • Pylint: Общий статический анализ (не фокусируется на безопасности).
  • Semgrep: Межъязыковой инструмент с поддержкой Python.

Заключение

Bandit — обязательный инструмент в арсенале Python-разработчика. Он обеспечивает быстрый и эффективный скан кода, снижая риски безопасности на ранних этапах. Хотя он не заменяет полноценный аудит, его интеграция в CI/CD создает мощный “щит” против базовых уязвимостей. В мире, где один пропущенный pickle.load() может стоить миллионов, Bandit — это не опция, а необходимость.

Ссылки: