mcpField
A
auditing-python-security

auditing-python-security

github.com/wdm0006セキュリティ109192 回インストール2 日前に更新
リポジトリ

auditing-python-security について

Python Security Auditingは、セキュリティスキャナーと安全なコーディングのチェックでPythonプロジェクトを監査するスキルです。CIの手順に加え、一般的な脆弱性やトレースバックからの秘密情報漏えいを防ぐ方法を扱います。

主な機能

  1. 014種類のセキュリティスキャナーの実行
  2. 02検出結果や実行失敗に応じたCI終了コード
  3. 03Banditとpip-auditの設定ガイド
  4. 04一般的な脆弱性の修正と安全なコード例
  5. 05トレースバックによるローカル変数漏えいの検査

活用シーン

  1. 01リリース前のPythonプロジェクトのスキャン
  2. 02セキュリティ検出結果に基づくCI制御
  3. 03依存関係の脆弱性チェック
  4. 04トレースバックで秘密情報が漏れないか確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wdm0006/python-skills --skill auditing-python-security

インストール後、Claude Code で/auditing-python-securityを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

CI_SECURITY.md
VULNERABILITIES.md
scripts/
security_scan.py

詳細

Python セキュリティ監査

クイックスタート

# Run all four scanners (gates CI): exit 1 on a blocking finding, exit 2 when a
# requested scanner could not run, exit 0 only when every scanner ran clean:
uv run python scripts/security_scan.py .

# Tolerate scanners that are missing or hung (restores exit 0 in that case):
uv run python scripts/security_scan.py . --allow-scanner-failure

# Or individually:
uvx bandit -r src/ -ll                       # High-severity static analysis
uvx pip-audit .                              # This project's dependencies
uvx semgrep --config auto src/               # Pattern-based SAST
uvx detect-secrets scan > .secrets.baseline  # Secrets detection

ツールの設定

Bandit (.bandit):

exclude_dirs: [tests/, docs/, .venv/]
skips: [B101]  # assert_used - OK in tests

pip-audit:

uvx pip-audit -r requirements.txt     # Scan requirements
uvx pip-audit --fix                   # Auto-fix vulnerabilities

よくある脆弱性

問題Bandit ID対処方法
SQL インジェクションB608プレースホルダーを使用したクエリを使います
コマンドインジェクションB602shell=True を指定せずに subprocess を使います
ハードコードされたシークレットB105, B106環境変数を使います
脆弱な暗号化B303SHA-256 以上を使い、パスワードには bcrypt を使います
信頼できないデータの Pickle 化B301代わりに JSON を使います
パストラバーサルB108Path.resolve() で検証します

セキュアなパターン

# SQL - Parameterized query
conn.execute("SELECT * FROM users WHERE id = ?", (user_id,))

# Commands - No shell
subprocess.run(["cat", filename], check=True)

# Secrets - Environment
API_KEY = os.environ.get("API_KEY")

# Paths - Validate
base = Path("/data").resolve()
file_path = (base / filename).resolve()
if not file_path.is_relative_to(base):
    raise ValueError("Invalid path")

トレースバックにフレームのローカル変数を出力しない

詳細な例外レンダラーは、スタックフレームごとにすべてのローカル変数を出力することがあります。 その結果、通常の未処理例外が認証情報の漏えいにつながります。トレースバックがターミナルや CI ログに出力される際、API トークン、 認可ヘッダー、リクエスト本文、復号済みの設定情報がローカル変数に含まれていることはよくあります。

ログが開発者のマシンから外部に出る可能性がある場所では、ローカル変数の出力を無効にしてください。

from rich.traceback import install

install(show_locals=False)

設定の呼び出しをアサートするだけでは不十分です。固有のダミーシークレットを使って、インストール済みの例外フックを実行し、出力内容を調べてください。これにより、後のリファクタリングでフックが置き換えられたり、別の場所でローカル変数の出力が再び有効になったりするケースを検出できます。

import sys


def test_unhandled_traceback_does_not_expose_locals(capsys):
    sentinel = "sentinel-secret-that-must-not-appear"

    try:
        raise RuntimeError("boom")
    except RuntimeError:
        exc_type, exc, traceback = sys.exc_info()
        sys.excepthook(exc_type, exc, traceback)

    output = capsys.readouterr()
    rendered = output.out + output.err
    assert "RuntimeError: boom" in rendered  # proves the hook rendered
    assert sentinel not in rendered

実際の認証情報は使わず、必ず一意のダミー値を使ってください。例外が出力されたことと、ダミー値が含まれていないことの両方をアサートしてください。出力が空、または出力処理が迂回されていても、セキュリティテストが無条件に合格しないようにする必要があります。

CI との統合

# .github/workflows/security.yml — full workflow in CI_SECURITY.md
- uses: astral-sh/setup-uv@v5
- run: uv run python scripts/security_scan.py . --output security-report.json

詳しいパターンについては、以下を参照してください。

  • scripts/security_scan.py — 4 つすべてのスキャナーを実行し、ブロッキング対象の検出結果がある場合(終了コード 1)、または要求されたスキャナーを実行できなかった場合(終了コード 2)に、ゼロ以外の終了コードを返します(--allow-scanner-failure で実行失敗を許容できます)(uv run python scripts/security_scan.py .)
  • VULNERABILITIES.md - 脆弱性の種類と、脆弱なコードから修正済みコードへのペア
  • CI_SECURITY.md - CI ワークフロー、pre-commit、Dependabot、トリアージの全容

監査チェックリスト

Code:
- [ ] No SQL injection (parameterized queries)
- [ ] No command injection (no shell=True)
- [ ] No hardcoded secrets
- [ ] Exception and logging configuration cannot render frame locals containing secrets
- [ ] No weak crypto (MD5/SHA1)
- [ ] Input validation on external data
- [ ] Path traversal prevention
- [ ] SSRF fetches connect to the validated IP on every redirect hop (DNS rebinding safe)
- [ ] SSRF deny policy covers IPv4/IPv6 and CGNAT (`100.64.0.0/10`)

Dependencies:
- [ ] pip-audit clean
- [ ] Minimal dependencies
- [ ] From trusted sources

CI:
- [ ] Security scan on every PR
- [ ] Weekly dependency scan

詳細情報

このスキルは、Will McGinnis による Guide to Developing High-Quality Python Libraries の Security セクションを基にしています。詳しい解説については、以下の記事を参照してください。

コメント