「管理者画面、ChatGPT に作らせたら 30 分でできた」――翌週、URL を 1 桁書き換えただけで他人の顧客リストが表示された。 2026 年、中堅企業のバイブコーディング (vibe coding = AI に書かせて雰囲気で作る開発スタイル) で最も多い実害は 認可漏れ (Broken Access Control) です。
「ログインさせれば安全」と思って作った管理画面が、ログイン後に URL のユーザー ID を 1 つずらすだけで他人の個人情報が見える ――OWASP Top 10 (2021) で A01:Broken Access Control が堂々の 1 位 に来ているのは偶然ではありません。OWASP の公式調査では、テスト対象アプリの 94% で何らかの認可不備が見つかっています (OWASP Top 10 2021 A01)。
AI 生成コードは「動く」が「認可をかける」とは限りません。本記事は連載「バイブコーディング危機」第 3 回として、認可と認証の違い、AI が書き忘れる 5 シーン、公開報道済の認可漏れ大事故 5 件、中堅企業向けの手動検知 10 項目、RBAC / ABAC / OPA による防衛、90 日教育プラン、既存システムの緊急対応 5 項目 までを完全版で整理します。
**連載「バイブコーディング危機」**は、AI で自社システムを開発する中堅企業向けに、専門家不在で起きるリスクを1 本ずつ深掘りします。 第 1 回(概論 + 7 リスク類型 + チェックリスト 10 項目) 第 2 回(SQL Injection の現実 5 パターン)
目次
- 「認可」と「認証」の違い(経営者向け 5 分解説)
- OWASP Top 10 (2021) A01 が 1 位の理由
- バイブコーディングが落とす 5 シーン(コード例つき)
- 公開報道済 認可漏れ大事故 5 件
- 中堅企業の手動検知 10 項目(負荷ゼロでできる)
- 中堅企業の防衛:RBAC / ABAC / OPA / Policy as Code
- 教育:エンジニア 1 名へ 90 日で認可設計スキル
- 既存システムの「今すぐ」やる緊急 5 項目
- よくある質問(FAQ 12 問)
- 参考一次ソース
「認可」と「認証」の違い(経営者向け 5 分解説)
経営者・情シス部長が 最初に押さえるべき 2 語 は「認証」と「認可」です。一字違いですが、意味も実装も全く別物です。
認証 (Authentication) = 「あなたは誰?」
ID / パスワード、Google アカウント、SAML SSO、ICカード、生体認証――システムに 「これは確かに山田太郎というユーザーです」と確認する プロセスです。バイブコーディングでも、AI に「ログイン作って」と頼めばだいたいログイン画面は出ます。
認可 (Authorization) = 「あなたに、何の権限がある?」
ログインした山田太郎が、どの画面を見て / どのデータを操作できる か、その境界を定義・強制するプロセスです。ここが認証と全く別の処理として実装されていないと、「ログインさえすれば全データ閲覧 OK」 という重大な認可不備が成立してしまいます。
例えで理解:「マンションのオートロック」と「各部屋の鍵」
- 認証 = マンションのオートロック (建物に入れるのは住人だけ)
- 認可 = 各部屋の鍵 (501 号室の住人は 502 号室を開けられない)
オートロックだけで部屋の鍵を全部開放したら、住人同士の部屋が全部覗ける マンションになります。それが「認証はあるが認可がない」状態 です。バイブコーディングの管理画面はこのパターンを量産します。
認可が「忘れられる」 3 つの構造的理由
- AI のデフォルトプロンプトは「ログインを作って」止まり: ChatGPT / Claude / Cursor は明示的に「ロールベース認可も実装して」と指定しないと、認証だけで止まる傾向があります
- 動作確認では気づかない: 自分でログインして自分のデータを見れば「動いている」と判定されます。他人のデータを取りに行く悪意のテスト を専門家不在では誰も行いません
- エラーが出ない: SQL Injection と違い、認可漏れは正常系として動きます。「あ、これおかしくない?」と気づく契機がありません
「動いている = 安全」とは限りません。「動いている」と「安全」の差 こそが、バイブコーディング危機の核心です。
AI ASSESSMENT
PoC の前に「そもそも使えるか」を30分で見極めませんか?
情シス部門の稟議書作成をサポートする無料の30分壁打ち。ROI 試算シート・失敗要因チェックリストをその場で共有します。
OWASP Top 10 (2021) A01 が 1 位の理由
OWASP (The Open Web Application Security Project) は Web セキュリティの国際標準を策定する非営利団体です。OWASP Top 10 は 4 年ごとに改訂される脆弱性ランキングで、世界中の開発者 / セキュリティチームが参照する事実上のデファクトです。
最新版 OWASP Top 10 2021 では、Broken Access Control (A01) が 2017 年版の 5 位から 1 位へ躍進 しました。理由は明確です。
数字で見る A01 の重み
OWASP 公式データ (A01:2021 公式ページ) より:
| 指標 | 値 |
|---|---|
| 平均的に「テスト対象アプリで A01 が検出される率」 | 94% |
| 関連 CWE (Common Weakness Enumeration) 件数 | 34 件 (CWE-200 / CWE-201 / CWE-352 / CWE-639 / 等) |
| Top 10 中の検出 CVE インシデント率 | A01 が最多 |
94% という数字は「テスト対象アプリのほぼ全部に何らかの認可不備が含まれていた」 という意味です。これが 1 位の論理的根拠です。
CWE で見る代表的な認可漏れ
- CWE-22 Path Traversal (
../../etc/passwdで任意ファイル読み) - CWE-200 Information Exposure (権限のないユーザーへの情報露出)
- CWE-285 Improper Authorization (認可処理の欠落・誤実装)
- CWE-352 Cross-Site Request Forgery (CSRF) (認可付きリクエストの偽造)
- CWE-425 Forced Browsing (URL 直叩きで保護されたページへ到達)
- CWE-639 Authorization Bypass Through User-Controlled Key (URL パラメータ書き換えで他人データ閲覧 = IDOR)
- CWE-862 Missing Authorization (認可チェックそのものが書かれていない)
このうち CWE-639 (IDOR: Insecure Direct Object Reference) は、バイブコーディングで 圧倒的に量産される タイプです。
Verizon DBIR でも上位の常連
Verizon「Data Breach Investigations Report (DBIR)」は世界最大規模のインシデント分析レポートです (Verizon DBIR)。
直近 5 年の傾向:
- Misconfiguration (設定ミス / 認可不備含む) がインシデント原因 Top 5 の常連
- 中小・中堅企業 (
Small Businessセグメント) で特に多い - Human error (人為ミス) が約 74% に関与、認可設計の見落としもここに含まれる
国内:IPA「情報セキュリティ 10 大脅威」
IPA 情報セキュリティ 10 大脅威 2026 (組織編) では、関連脅威として以下が常時上位です。
- 不注意による情報漏えい等の被害 (※認可設計ミスを含む)
- 内部不正による情報漏えい
- テレワーク等のニューノーマルな働き方を狙った攻撃
特に「不注意による情報漏えい」は バイブコーディング起因の認可漏れと重なる典型カテゴリ です。
バイブコーディングが落とす 5 シーン(コード例つき)
ここからが本記事の核心です。AI 生成コードが書き忘れる 5 シーン を、現実に起きるコード例つきで整理します。
シーン 1: URL 直叩きで他人データ閲覧 (IDOR / CWE-639)
頻度: バイブコーディング案件で 圧倒的 1 位
脆弱なコード(AI に「ユーザープロフィール画面作って」と頼んだ初期生成)
# Flask の例(脆弱)
@app.route('/user/<int:user_id>')
@login_required # 認証はある
def show_user(user_id):
user = User.query.get(user_id)
return render_template('profile.html', user=user)
何が抜けているか: current_user.id == user_id の検証がありません。ログイン後、URL を /user/1 → /user/2 と書き換えるだけで、任意の他人プロフィールが見えてしまいます。
正しいコード
@app.route('/user/<int:user_id>')
@login_required
def show_user(user_id):
if current_user.id != user_id and not current_user.is_admin:
abort(403) # 自分 or 管理者のみ閲覧可
user = User.query.get_or_404(user_id)
return render_template('profile.html', user=user)
シーン 2: 管理画面の role check 漏れ (CWE-285 / CWE-862)
頻度: バイブコーディング案件で 2 位
脆弱なコード(AI に「管理画面作って」と頼んだ初期生成)
# 全 admin 機能のうち、1 つだけ admin_required 忘れ
@app.route('/admin/users')
@login_required
@admin_required # ある
def admin_users():
...
@app.route('/admin/delete_user/<int:user_id>', methods=['POST'])
@login_required # admin_required が抜けとる
def admin_delete_user(user_id):
User.query.filter_by(id=user_id).delete()
db.session.commit()
return redirect('/admin/users')
何が抜けているか: /admin/delete_user/<user_id> の POST 経路だけ admin_required が抜けています。AI に「コピペで複数 endpoint 作って」と頼むと、こういう 「コピペ漏れ」 が頻発します。
正しい対策
- 管理画面は Blueprint / Router を分離し、全 endpoint に
admin_requiredを一括適用する - 個別 decorator ではなく before_request hook で全体強制する
# Flask Blueprint パターン
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
@admin_bp.before_request
@login_required
@admin_required
def require_admin():
pass
@admin_bp.route('/users')
def admin_users():
...
@admin_bp.route('/delete_user/<int:user_id>', methods=['POST'])
def admin_delete_user(user_id): # before_request で admin 強制済
...
シーン 3: row-level 認可漏れ (CWE-639 の DB クエリ版)
頻度: SaaS 多テナント / 業務システムで頻発
脆弱なコード(AI に「注文履歴一覧 API 作って」と頼んだ初期生成)
@app.route('/api/orders')
@login_required
def list_orders():
orders = Order.query.all() # 全件返してしまう
return jsonify([o.to_dict() for o in orders])
何が抜けているか: Order.query.filter_by(user_id=current_user.id) がありません。ログインさえすれば 全ユーザーの全注文が API で見えてしまいます。
正しいコード
@app.route('/api/orders')
@login_required
def list_orders():
orders = Order.query.filter_by(user_id=current_user.id).all()
return jsonify([o.to_dict() for o in orders])
シーン 4: ファイルアップロード / ダウンロード経路の認可無し (CWE-22)
頻度: 帳票 / 領収書 / 添付ファイル系で頻発
脆弱なコード(AI に「PDF ダウンロード機能作って」と頼んだ初期生成)
@app.route('/download/<filename>')
@login_required
def download(filename):
return send_from_directory('uploads', filename)
何が抜けているか:
- path traversal:
filename = "../../etc/passwd"でサーバー任意ファイルを取得可能になります - 認可漏れ: ファイル名さえ知っていれば他人の請求書もダウンロード可能になります
正しいコード
import os
from werkzeug.utils import secure_filename
@app.route('/download/<int:file_id>')
@login_required
def download(file_id):
file = UploadedFile.query.get_or_404(file_id)
if file.user_id != current_user.id and not current_user.is_admin:
abort(403)
safe_name = secure_filename(file.filename)
return send_from_directory('uploads', safe_name)
ポイント:
- ファイル ID 経由で DB から
user_idを引いて認可チェック secure_filenameで path traversal 防止- ファイル名そのまま URL に出さない(推測されると困る)
シーン 5: API endpoint がデフォルト公開 (CWE-285 / CWE-306)
頻度: 「とりあえず API 動かしたい」フェーズで多発
脆弱なコード(AI に「フロントから叩く API 作って」と頼んだ初期生成)
# FastAPI の例(認証ミドルウェアが入ってない)
@app.get('/api/users/{user_id}')
def get_user(user_id: int):
user = db.query(User).filter(User.id == user_id).first()
return user
何が抜けているか: 認証も認可も一切ありません。URL を知っている人は誰でも (= ボット含めて世界中から) 任意ユーザーの情報を取れてしまいます。
正しい対策
- デフォルトを「認証必須」にする global middleware を入れる
- 明示的に
@publicを付けた endpoint のみ未認証許可とする - API key / JWT / OAuth Bearer Token を必須化する
# FastAPI 推奨パターン
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')
async def get_current_user(token: str = Depends(oauth2_scheme)):
user = decode_jwt(token)
if not user:
raise HTTPException(status_code=401)
return user
@app.get('/api/users/{user_id}')
def get_user(user_id: int, current_user: User = Depends(get_current_user)):
if current_user.id != user_id and not current_user.is_admin:
raise HTTPException(status_code=403)
return db.query(User).filter(User.id == user_id).first()
公開報道済 認可漏れ大事故 5 件
ここでは、メディア / 公式 IR / 規制当局公表で確認できる 公開報道済の認可漏れインシデント 5 件 を整理します。各事案は出典 URL を併記します。
注記: 各事案は 当時の技術的状況・組織体制下で発生したもの であり、「バイブコーディング起因」と断定するものではありません。中堅企業のバイブコーディング環境で 同種の認可漏れパターンが発生する確率が高い という観点で参照します。
事案 1: First American Financial Corporation (2019) — 約 8.85 億件流出
概要: 米国大手の不動産タイトル保険会社 First American Financial Corp。2019 年 5 月、Web サイトの URL を 1 桁書き換えるだけで 顧客の不動産取引文書 (社会保障番号 / 銀行口座 / 取引履歴 / 運転免許証) が 約 8 億 8,500 万件 閲覧可能だった事実が判明しました。
技術的原因: 典型的な IDOR (Insecure Direct Object Reference) です。URL に文書 ID (連番) が含まれており、認証不要で他人の文書が見えていました。
結果: 2023 年、ニューヨーク州金融サービス局 (NYDFS) が 100 万ドルの罰金 を科しました。米国サイバーセキュリティ規制 (NYDFS Cybersecurity Regulation 23 NYCRR Part 500) 初の重大違反案件 です。
出典:
事案 2: Optus (2022, オーストラリア) — 約 980 万人分の顧客データ流出
概要: 豪 2 位の通信キャリア Optus。2022 年 9 月、API endpoint の認可不備で 過去・現在の顧客 980 万人分 の個人情報 (氏名 / 生年月日 / 住所 / 運転免許番号 / パスポート番号 / Medicare 番号) が流出。
技術的原因: 認証不要の API endpoint が公開状態でした。顧客 ID を連番で総当たりすれば全件取得可能だったとされています (報道 by Australian Information Commissioner / 公開資料)。
結果:
- 集団訴訟提起 (報道による)
- 豪通信規制当局 ACMA / OAIC による調査
- 2026 年時点でも訴訟係属中 (報道による)
出典:
事案 3: Peloton (2021) — 認可不要 API で全ユーザー情報露出
概要: 米フィットネス機器メーカー Peloton。2021 年 1 月、認証不要の API endpoint で、Peloton ユーザー (バラク・オバマ元大統領を含む高名人多数) の 個人情報・ワークアウト履歴・身長体重等 がアクセス可能でした。
技術的原因: 「private」設定にしたユーザーの情報も含めて、API はログイン不要で全データを返していました。CWE-285 (Improper Authorization) の教科書事例です。
結果: TechCrunch による報道後、Peloton が緊急パッチを適用しました。3 ヶ月放置されていた事実も報道されました。
出典:
事案 4: USPS (2018) — 「Informed Visibility」API で 6,000 万人露出
概要: 米郵政公社 USPS。2018 年 11 月、配達追跡 API「Informed Visibility」で、ログインユーザー全員 (= 約 6,000 万人) が、他ユーザーのアカウント情報 (氏名 / 住所 / 電話 / メール / フォローしている荷物番号等) を閲覧可能 だった事実が判明しました。
技術的原因: API のクエリパラメータ (検索条件) を変えるだけで、他人データへのフィルタが可能でした。row-level 認可漏れ (CWE-639) の大規模事例です。
結果: 報道 1 日後に修正が完了しました。USPS は事前にバグレポートを 1 年間放置していた事実も判明しています。
出典:
事案 5: T-Mobile (2023) — API 認可不備で 3,700 万件流出
概要: 米 T-Mobile。2023 年 1 月、API endpoint の認可不備により 約 3,700 万人の顧客情報 (氏名 / 請求住所 / メール / 電話 / 生年月日 / アカウント番号 / プラン情報) が流出。
技術的原因: T-Mobile 公式 SEC Form 8-K より、「単一の API がデータの不正取得に悪用された」 と開示されました。具体的には API key の認可スコープを超えたデータ取得が可能だったとされています (報道による)。
結果: T-Mobile は SEC 開示で違反を公表しました (2023-01-19)。過去 5 年で 9 度目 の T-Mobile データ流出として、規制当局・株主からの批判が拡大しました。
出典:
5 件の共通パターン
| 共通点 | 該当事案 |
|---|---|
| API endpoint がデフォルトで認証 / 認可なし | Peloton / USPS / T-Mobile |
| URL / クエリパラメータ書き換えで他人データ | First American / USPS |
| 認可スコープの設計漏れ | T-Mobile / Optus |
| バグレポート受理後の対応遅延 | USPS (1 年) / Peloton (3 ヶ月) |
| 規制当局 / 集団訴訟リスク | First American / Optus / T-Mobile |
中堅企業のバイブコーディング環境では、これら 5 つすべての構造的要因が同時に成立しやすくなります。
中堅企業の手動検知 10 項目(負荷ゼロでできる)
専門ツール / 外部監査を入れる前に、情シス 1 名でできる手動チェック 10 項目 を整理します。所要時間は 2-3 日、コストは 0 円です。
検知 1: URL のユーザー ID / 注文 ID / ファイル ID 書き換えテスト
手順:
- アプリケーションにテストユーザー A (id=1) でログイン
- プロフィール画面
/user/1を開く - URL を
/user/2/user/100等に書き換える - 他人データが表示されたら IDOR 確定
所要時間: 全画面で 30 分
検知 2: 管理画面 URL を一般ユーザーで叩く
手順:
- テストユーザー B (一般権限) でログイン
/admin/admin/users/admin/settings等を直接アクセス- 画面が表示されたら role check 漏れ確定
- POST 系 (
/admin/delete_user/1) もcurl/ Postman で叩く
所要時間: 1 時間
検知 3: ログアウト後の URL 直叩き
手順:
- ログイン状態でブラウザに URL コピー
- ログアウト
- コピーした URL を再度貼り付けて Enter → 開けたら認証 middleware 漏れ
所要時間: 15 分
検知 4: 異ユーザーで他者の編集 / 削除 POST
手順:
- ユーザー A の投稿 ID を確認 (
/post/123) - ユーザー B でログイン
- B の権限で
DELETE /post/123やPUT /post/123を叩く (Postman / curl) - 200 / 204 が返ったら認可漏れ
所要時間: 1 時間
検知 5: ファイル ID / ファイル名の総当たり
手順:
- 自分の請求書 PDF をダウンロード (
/download/abc-2026-05-001.pdf) - ファイル名規則を推測 (
/download/abc-2026-05-002.pdf等) - 他人のファイルが落ちてきたら認可漏れ
所要時間: 30 分
検知 6: API レスポンスを開発者ツールで全件確認
手順:
- ブラウザ DevTools → Network タブ
- アプリで通常操作 (注文一覧開く等)
- API レスポンス JSON を全文確認 → 自分以外のユーザー ID / メールアドレス / 個人情報が含まれていたら row-level 漏れ確定
所要時間: 2 時間 (主要画面網羅)
検知 7: GraphQL / REST API のスキーマ公開チェック
手順:
/graphql/api-docs/swagger.json/openapi.json等を未認証でアクセス- スキーマが見えたら攻撃者にも見えとる
- 本番では認可 or 削除推奨
所要時間: 15 分
検知 8: HTTP method の検証 (GET / POST / PUT / DELETE / PATCH)
手順:
- 認可された GET endpoint を確認
- 同 URL に POST / PUT / DELETE を叩く (curl / Postman)
- 405 (Method Not Allowed) ではなく 200 / 500 が返ったら危険信号
所要時間: 1 時間
検知 9: HTTP ヘッダで権限偽装
手順:
X-User-Id: 1X-Role: admin等を任意設定して送信- アプリがヘッダを信用していたら認可ロジック崩壊
所要時間: 30 分
検知 10: JWT / セッションのペイロード書き換え
手順:
- ログイン後のセッション cookie / JWT を取得
- JWT なら jwt.io でデコード →
role: userをrole: adminに書き換えて再エンコード - 書き換えた JWT が通ったら署名検証漏れ確定
所要時間: 1 時間
検知後の優先順位付け
| 検知項目 | 影響度 | 即時対応 |
|---|---|---|
| IDOR (検知 1, 4, 5) | 致命 (全顧客データ流出) | 24h 以内 |
| 管理画面アクセス (検知 2) | 致命 (システム破壊リスク) | 24h 以内 |
| API 認証漏れ (検知 6, 7) | 致命 | 24h 以内 |
| JWT 改ざん (検知 10) | 致命 | 24h 以内 |
| その他 (検知 3, 8, 9) | 高 | 1 週間以内 |
中堅企業の防衛:RBAC / ABAC / OPA / Policy as Code
検知で穴が見つかったら、次は 構造的に認可を強制する設計 へ進みます。中堅企業向けに 4 段階で整理します。
段階 1: RBAC (Role-Based Access Control) - 規模 50 名以下
仕組み: ユーザーに「ロール」を割り当て、ロールごとに「できる操作」を定義。最も基本かつ実装容易。
実装例 (Django):
# Django Permissions パターン
from django.contrib.auth.decorators import permission_required
@permission_required('orders.view_all_orders')
def admin_order_list(request):
return render(request, 'admin/orders.html', {'orders': Order.objects.all()})
@permission_required('orders.view_own_orders')
def my_orders(request):
return render(request, 'my_orders.html', {'orders': request.user.orders.all()})
ロール例:
admin(全権限)manager(自部署メンバーのデータ閲覧 / 編集)member(自分のデータのみ)guest(read-only)
メリット: 実装シンプル、Django / Laravel / Rails の標準 helper で対応可能 デメリット: 「営業 A は 顧客 X だけ見える」のような インスタンス単位の認可 は表現困難
段階 2: ABAC (Attribute-Based Access Control) - 規模 50-500 名
仕組み: ユーザー / リソース / 環境 (時刻 / IP 等) の属性を組み合わせたポリシーで認可。
参考: NIST SP 800-162 (Guide to Attribute Based Access Control)
実装例 (ポリシーの記述):
# 「営業担当 A は、自分が assign された顧客のデータだけ閲覧可能」
def can_view_customer(user, customer):
if user.role == 'admin':
return True
if user.role == 'sales' and customer.assigned_to == user:
return True
if user.role == 'manager' and customer.assigned_to.department == user.department:
return True
return False
メリット: 複雑な業務ルールを表現可能 デメリット: ポリシー管理コスト上昇、テスト容易性低下
段階 3: Policy as Code with OPA (Open Policy Agent) - 規模 500 名以上 or 認可ロジック複雑化
仕組み: 認可ロジックをアプリコードから分離し、専用ポリシー言語 Rego で記述。
参考: Open Policy Agent (OPA) 公式 / Rego Policy Language
Rego 例:
package authz
default allow = false
# 管理者は全許可
allow {
input.user.role == "admin"
}
# 営業は自分の顧客のみ
allow {
input.user.role == "sales"
input.resource.type == "customer"
input.resource.assigned_to == input.user.id
}
# マネージャーは自部署の顧客全部
allow {
input.user.role == "manager"
input.resource.type == "customer"
input.resource.department == input.user.department
}
メリット:
- アプリと認可ロジックの分離 (アプリは「OPA に聞くだけ」)
- ポリシー変更がデプロイ不要 (ホットリロード可)
- テスト容易 (Rego unit test 標準サポート)
デメリット: 学習コスト、運用基盤必要
段階 4: Zero Trust + Service Mesh
仕組み: マイクロサービス間通信も含めて、全リクエストを認可 (Istio / Envoy / Linkerd で実装)。
参考: NIST SP 800-207 (Zero Trust Architecture)
中堅企業適用シーン: マイクロサービス化 / クラウド移行が進んだ規模 (500-3,000 名規模)
中堅企業の選び方フロー
従業員 50 名以下 + 単一アプリ → RBAC (段階 1)
従業員 50-500 名 + 複数業務システム → ABAC (段階 2)
従業員 500 名以上 / 認可ロジックが複雑 → OPA (段階 3)
クラウドネイティブ / マイクロサービス → Zero Trust + Service Mesh (段階 4)
ほとんどの中堅企業は段階 1 か 2 で十分です。最初から OPA を入れる必要はありません。
教育:エンジニア 1 名へ 90 日で認可設計スキル
中堅企業の情シス 1-3 名体制で、外部研修なしで認可設計スキルを 90 日で習得 するためのプランです。
Week 1-2: 基礎理解 (10h)
学習内容:
- 認証 vs 認可の違い
- OWASP Top 10 2021 (特に A01) 公式読破
- CWE Top 25 のうち認可関連 (CWE-22 / 200 / 285 / 352 / 425 / 639 / 862) を理解
教材:
ゴール: 自社のコードを「認証はある / 認可は?」の視点で読み返せるようになる
Week 3-4: 自社アプリ手動監査 (20h)
実施内容:
- 本記事「中堅企業の手動検知 10 項目」を全画面で実施
- 発見した穴を Issue / チケット起票
- 致命的脆弱性は 24h 以内に修正
ゴール: 自社の認可漏れリスクを 数値化 (例: 30 endpoint 中 12 件で IDOR 確認)
Week 5-6: RBAC / ABAC 実装 (30h)
実施内容:
- 既存アプリに RBAC を導入 (Django Permissions / Laravel Gates / Spring Security)
- ロール定義 (admin / manager / member 等)
- 各 endpoint に
@permission_required適用 - ABAC が必要な箇所のみ追加
ゴール: 管理画面と一般画面の認可境界が コード上で明示 されている
Week 7-8: テスト自動化 (15h)
実施内容:
- 認可テストを単体テストに追加 (
test_admin_only.py等) - 各 endpoint に対し「権限あり ユーザーが 200」「権限なし ユーザーが 403」を assert
- CI で自動実行
コード例 (pytest):
def test_admin_can_delete_user(admin_client):
resp = admin_client.post('/admin/delete_user/1')
assert resp.status_code == 302 # redirect after success
def test_normal_user_cannot_delete(user_client):
resp = user_client.post('/admin/delete_user/1')
assert resp.status_code == 403
def test_unauthenticated_redirected_to_login(client):
resp = client.post('/admin/delete_user/1')
assert resp.status_code in (302, 401)
ゴール: 認可漏れが デプロイ前 CI で検知 される体制
Week 9-10: バグ報奨金 / ペネトレ準備 (10h)
実施内容:
- 外部ペネトレーションテスト業者にスコープ依頼 (年 1 回 30-100 万円)
- バグ報奨金プログラム (HackerOne / BugCrowd) 検討
- 内部「ハッカーごっこデー」 (社内エンジニアで認可テスト) の設計
ゴール: 外部監査の発注先候補が 2-3 社見えている
Week 11-12: ポリシー文書化 + Onboarding (5h)
実施内容:
- 認可設計ポリシーを
docs/authorization-policy.mdに成文化 - 新規エンジニア onboarding チェックリストに「Week 1-4 を実施」を追加
- 認可漏れインシデント発生時の対応手順書
ゴール: スキルが 個人 → 組織 に定着
90 日後の到達目標
- 自社アプリの認可漏れ箇所が全て修正済
- CI で自動認可テスト稼働
- RBAC / ABAC 設計がコード上で明示
- 認可ポリシーが成文化
- 年 1 回外部ペネトレ発注ルーチン化
コスト: 外部研修 0 円、専門書 5,000 円、ペネトレ予算 30-100 万円 (年 1 回)
既存システムの「今すぐ」やる緊急 5 項目
「90 日プランは分かった、でも来週何をする?」という経営者向けに、今週中にやる 5 項目 を示します。
緊急 1: 管理画面 URL に全社員でアクセスして role check 確認 (1h)
- 社員 5 名に「これ開いてみて」と Slack で URL 投げる
- 通常権限の社員に管理画面が表示されたら 即時停止
- 24h 以内に Web サーバー側で IP 制限 or ベーシック認証追加
緊急 2: API endpoint を未認証でブラウザに直接アクセス (30 分)
# 認証なしで叩く
curl https://your-app.com/api/users
curl https://your-app.com/api/orders
curl https://your-app.com/api/customers
- 200 OK で JSON が返ったら認証 middleware 漏れ確定
- API gateway / nginx で 未認証リクエストを 401 で叩き返す 設定追加
緊急 3: 「自分のデータが他人に見えていないか」を顧客視点で確認 (30 分)
- 自社サービスに テストアカウント 2 つ作成
- アカウント A でログイン → URL コピー
- アカウント B でログイン → A の URL を貼って開く
- A のデータが見えたら IDOR 確定
緊急 4: ログイン後の URL を「ログアウト状態」で叩く (15 分)
- ログイン後の各画面 URL を ログアウトしたブラウザ で開く
- 画面が表示される (= 認証 middleware 漏れ) なら緊急対応
緊急 5: 過去のログから「不正アクセス兆候」を抜き出す (1-2h)
# nginx ログから連番 URL の総当たり兆候を検出
awk '{print $7}' /var/log/nginx/access.log | grep -E '/user/[0-9]+' | sort | uniq -c | sort -rn | head -50
# 短時間に 100+ 件の連番アクセスがあれば総当たり攻撃の可能性
- 1 IP から 100 件以上の連番アクセス があったら IDOR 攻撃を疑う
- 該当 IP を即時 block + 該当ユーザーに通知
5 項目で見つかったら、72h 以内にやる
- 該当 endpoint を緊急パッチ (認可チェック追加 or 一時停止)
- 影響範囲調査 (どこまで見えたか / 流出件数)
- 個情委 (個人情報保護委員会) 報告判断 (改正個情法 72h 報告義務)
- 顧客通知判断 (改正個情法 本人通知義務)
- インシデント記録残し (時系列 / 対応 / 再発防止)
参考: 個人情報保護委員会「個人情報の漏えい等の事案が発生した場合の対応について」
よくある質問(FAQ 12 問)
Q1. AI で書いたコードを認可レビューする時間がないのですが、コスパはどうでしょうか?
A. 認可漏れ 1 件で 1 億円規模の流出 / 訴訟 が起き得ます (First American: NYDFS 100 万ドル罰金、Optus: 集団訴訟係属中)。90 日プランの工数 90h × 1 人分 ≈ 50-100 万円です。ROI は明白です。
Q2. ChatGPT / Claude / Cursor に「認可も含めて書いて」と指定すれば防げるでしょうか?
A. 大きく改善しますが完全ではありません。AI 生成コードでも、複雑な認可ルール (営業 A は顧客 X のみ等) は 指定漏れ / 解釈ズレで穴が出ます。AI の出力 → 手動レビュー + 自動テスト の二段構えが必須です。
Q3. RBAC と ABAC、どちらから始めればよいでしょうか?
A. RBAC からです。50 名以下の組織なら RBAC で十分です。複雑なルール (assign / department 連動等) が出てきた段階で ABAC に拡張します。最初から ABAC を選ぶと過剰設計でメンテが困難になります。
Q4. OPA (Open Policy Agent) は中堅企業に必要でしょうか?
A. 規模 500 名以上 or マイクロサービス化 していなければ不要です。Django Permissions / Laravel Gates / Spring Security の標準機能で十分です。OPA は学習コストと運用基盤コストが大きいです。
Q5. JWT を使えば認可は完璧でしょうか?
A. いいえ。JWT は 認証 の仕組みです。認可は別途実装が必要です。さらに JWT 自体に脆弱性パターン (alg: none / 弱い秘密鍵 / refresh token 漏れ等) があり、role を JWT に埋めるなら署名検証 + 鍵管理 + 失効処理が必須です。
Q6. WAF (Web Application Firewall) で防げるでしょうか?
A. 部分的に防げます。WAF は SQL Injection / XSS / 既知の攻撃パターンには有効です。しかし 業務ロジックレベルの認可漏れ (IDOR / row-level 漏れ) は WAF では検知困難です。WAF は補助であり、本質はアプリ側の認可設計です。
Q7. ログイン画面に MFA (多要素認証) を入れれば認可漏れは防げるでしょうか?
A. いいえ。MFA は 「正規ユーザー本人」かを確認する認証強化 です。ログイン後に他人データが見える IDOR は MFA では防げません。認証強化と認可は別問題です。
Q8. 認可テストを書くのに React / Vue のフロントエンドだけで十分でしょうか?
A. 絶対にいいえ。フロントエンドで「ボタンを隠す」のは UX 上の措置です。API / バックエンド側で認可チェックをしていないと、curl / Postman で直接叩かれた瞬間に全データが取れてしまいます。「フロントで隠した = 安全」は最も多い誤解です。
Q9. SaaS / クラウドサービス (Salesforce / kintone 等) を使えば認可問題は解決するでしょうか?
A. 基本機能は解決しますが、カスタマイズ部分は別です。Salesforce のカスタムオブジェクト / Apex / kintone のカスタマイズ JavaScript で 「権限なし」と書き忘れ たら同じ問題が発生します。バイブコーディング (Apex / JavaScript / カスタムビュー設定) でも認可漏れは起き得ます。
Q10. 認可漏れが流出につながった場合の法的対応はどうなるでしょうか?
A. 改正個人情報保護法 (2022 年 4 月施行) で、漏えい等が発生した場合、72 時間以内に個人情報保護委員会へ報告 + 本人通知 の義務があります。違反には 1 億円以下の罰金 + 経営層の刑事責任 があります。参考: 改正個情法ガイドライン
Q11. 認可漏れ監査は内製と外注、どちらがコスパが良いでしょうか?
A. 両方併用が理想です。内製で 90 日プラン → 年 1 回 外部ペネトレ が中堅企業の現実解です。内製のみだと盲点 (社内の常識化したバグ) が見つかりません。外注のみだとコストが高く、即時性も低くなります。
Q12. AI が書いた認可ロジックは、AI に「監査して」と頼めば検知できるでしょうか?
A. 部分的に有効です。Cursor / Claude Code に「このコードの認可漏れを指摘して」と聞けば、典型パターン (IDOR / role check 漏れ) は検出できる場合があります。ただし AI の出力は鵜呑みにせず、手動チェック + テスト自動化と組み合わせてください。AI を「監査の最初の網」として使うのは現実的です。
参考一次ソース
本記事の事実認定で参照した一次ソース一覧:
国際標準 / OWASP
- OWASP Top 10 2021 - A01:Broken Access Control
- OWASP Authorization Cheat Sheet
- OWASP Access Control Testing Guide
- OWASP API Security Top 10 2023
CWE (Common Weakness Enumeration)
- CWE-22 Path Traversal
- CWE-285 Improper Authorization
- CWE-639 Authorization Bypass Through User-Controlled Key (IDOR)
- CWE-862 Missing Authorization
NIST 公式
- NIST SP 800-162 (Guide to Attribute Based Access Control)
- NIST SP 800-207 (Zero Trust Architecture)
- NIST NVD (National Vulnerability Database)
国内公的機関
報道 / 公式 IR
- NYDFS First American 罰金プレスリリース (2023)
- Krebs On Security - First American (2019-05)
- OAIC Optus 調査公表 (2022)
- TechCrunch - Peloton API バグ (2021-05)
- Krebs On Security - USPS API (2018-11)
- T-Mobile 公式 (2023-01)
ツール / OSS
まとめ:認可は「動く」ではなく「漏れない」の世界
本記事の要点を 7 行でまとめます。
- 認証と認可は別物です。AI に「ログイン作って」と頼んでも認可は出てこない場合が多いです
- OWASP Top 10 2021 で A01 が 1 位 で、テスト対象アプリの 94% で何らかの認可不備が見つかります
- バイブコーディングが落とす 5 シーン は、IDOR / role check 漏れ / row-level 漏れ / ファイル経路 / API デフォルト公開です
- 公開報道済 5 件 (First American 8.85 億件 / Optus 980 万人 / Peloton 全員 / USPS 6,000 万人 / T-Mobile 3,700 万人) は全部同類パターンです
- 手動検知 10 項目 で情シス 1 名・2-3 日・コスト 0 円で全社チェックが可能です
- 防衛は RBAC → ABAC → OPA の 3 段階です。中堅企業は段階 1-2 で十分です
- 緊急 5 項目 で今週中に着手し、90 日プランで組織スキルを定着させます
「動いている」と「漏れない」の差を、AI 時代の中堅企業はもう一度自覚する時です。次回 (連載第 4 回) は サービス停止の財務影響:江崎グリコ 4 ヶ月の教訓と中堅企業の BCP 設計 を取り上げます。
関連記事
「うちの認可、本当に大丈夫?」と思ったら
GXO の バイブコーディング監査 + セキュリティ顧問サービス では、中堅企業向けに以下を提供します:
- 認可漏れ手動監査 (本記事の検知 10 項目を専門家が代行、3-5 営業日)
- RBAC / ABAC 設計レビュー (既存システムへの段階導入支援)
- 90 日教育プラン カスタマイズ (情シス 1-3 名向け実地研修)
- インシデント発生時 緊急対応 (改正個情法 72h 報告 + 影響範囲調査)
著者: GXO株式会社 初回公開: 2026 年 5 月 23 日 最終更新: 2026 年 5 月 23 日 連載: バイブコーディング危機 第 3 回(全 20 回)
