auditing-python-security について
Python Security Auditingは、セキュリティスキャナーと安全なコーディングのチェックでPythonプロジェクトを監査するスキルです。CIの手順に加え、一般的な脆弱性やトレースバックからの秘密情報漏えいを防ぐ方法を扱います。
主な機能
- 014種類のセキュリティスキャナーの実行
- 02検出結果や実行失敗に応じたCI終了コード
- 03Banditとpip-auditの設定ガイド
- 04一般的な脆弱性の修正と安全なコード例
- 05トレースバックによるローカル変数漏えいの検査
活用シーン
- 01リリース前のPythonプロジェクトのスキャン
- 02セキュリティ検出結果に基づくCI制御
- 03依存関係の脆弱性チェック
- 04トレースバックで秘密情報が漏れないか確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wdm0006/ python-skills --skill auditing-python-securityインストール後、Claude Code で/auditing-python-securityを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CI_SECURITY.mdVULNERABILITIES.mdscripts/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 | プレースホルダーを使用したクエリを使います |
| コマンドインジェクション | B602 | shell=True を指定せずに subprocess を使います |
| ハードコードされたシークレット | B105, B106 | 環境変数を使います |
| 脆弱な暗号化 | B303 | SHA-256 以上を使い、パスワードには bcrypt を使います |
| 信頼できないデータの Pickle 化 | B301 | 代わりに JSON を使います |
| パストラバーサル | B108 | Path.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 セクションを基にしています。詳しい解説については、以下の記事を参照してください。