【ITニュース解説】BOLA, the #1 API Vulnerability: a One-Line Fix and an A-B Test in Go and PHP
2026年10月29日に「Dev.to」が公開したITニュース「BOLA, the #1 API Vulnerability: a One-Line Fix and an A-B Test in Go and PHP」について初心者にもわかりやすく解説しています。
ITニュース概要
BOLAは、APIでURLのIDを変えるだけで他人のデータが見えてしまう脆弱性。ログイン中のユーザーがそのデータの持ち主かをコードで確認する「認可チェック」が必須だ。通常のテストでは見つけにくいため、異なるユーザーで他人のデータへのアクセスを試す「A-Bテスト」を実施し、安全性を確かめることが重要だ。
ITニュース解説
システムエンジニアを目指す皆さんにとって、ウェブアプリケーションのセキュリティは避けて通れない重要なテーマだ。特に、API(アプリケーション・プログラミング・インターフェース)は現代のシステムにおいてデータのやり取りの基盤となっており、そのセキュリティは非常に重要視されている。今回解説する「BOLA」は、APIにおける最も深刻な脆弱性の一つで、OWASP(オープン・ウェブ・アプリケーション・セキュリティ・プロジェクト)が発表する2023年のAPI脆弱性ランキングでトップに位置している。
BOLAは「Broken Object Level Authorization」の略で、日本語にすると「オブジェクトレベルの認可の欠陥」となる。これは、特定のデータ(例えば、請求書やユーザー情報といった「オブジェクト」)へのアクセス権限(「認可」)のチェックが適切に行われていないために発生する脆弱性だ。具体的な例を挙げよう。ある請求書アプリケーションで、ログインしているユーザーが自分の請求書にアクセスしようと、「GET /invoices/7f3b」というURLを介してAPIにリクエストを送ったとする。APIはユーザーの請求書を返し、処理が成功したことを示す「200 OK」というレスポンスを返す。ここまでは問題ない。
しかし、もしそのユーザーがURLの請求書IDを「7f3b」から「7f3a」のように少しだけ変更して、再度APIにリクエストを送ったらどうなるだろうか。もしAPIが「200 OK」を返し、変更されたIDの請求書が他人のものであったとしたら、それはBOLA脆弱性があるということだ。この場合、ログインしているユーザーは自分のアカウントで、他人の請求書を簡単に閲覧できてしまう。この脆弱性は、IDOR(Insecure Direct Object Reference:安全でない直接オブジェクト参照)とも呼ばれる。
なぜこのような問題が起きるのだろうか。原因は「認証」と「認可」の混同、あるいは認可の欠如にある。「認証(Authentication)」とは「あなたが誰であるか」を確認することだ。システムにログインする際にIDとパスワードを入力し、あなたがBobであると確認されるのが認証だ。APIへのリクエストには、ログイン時に受け取ったトークンが送られるため、APIは「Bobからのリクエストである」と認識する。一方、「認可(Authorization)」とは「あなたが何にアクセスできるか」を確認することだ。Bobはログインしているが、他人の請求書にアクセスする権限を持っているのか、という点を確認するのが認可だ。BOLAの場合、システムはユーザーの認証はするが、特定のリソースにアクセスする「認可」があるかを適切にチェックし忘れているのだ。
この問題への対策として、「推測されにくい長いIDを使う」という方法を考える人もいるかもしれない。確かに、ランダムで長いIDを使えば、攻撃者がIDを一つずつ試して他人のデータを見つけ出すのは難しくなるだろう。OWASPも推奨しているが、これはあくまで「追加の対策」であり、根本的な解決にはならないと指摘されている。なぜなら、たとえ推測されにくいIDであっても、共有リンクやスクリーンショットなど、さまざまな経路でIDが漏洩する可能性は常にあるからだ。IDが一度攻撃者の手に渡れば、そのIDが示すデータが本当にそのユーザーのものであるかを確認する「所有者チェック」がなければ、攻撃を止めることはできない。
このBOLAのような脆弱性は、一般的な脆弱性スキャナーでは見つけにくいという特徴がある。ほとんどの脆弱性スキャナーは、単一のアカウントを使ってAPIにリクエストを送り、そのレスポンスを分析する。例えば、スキャナーが「GET /invoices/7f3a」というリクエストを送って「200 OK」という正常なレスポンスを受け取った場合、スキャナーは問題がないと判断してしまう。スキャナーには、その請求書が他人のものであるという情報がないからだ。
BOLAを見つけるためには、異なる二つのアカウントを使った「A-Bテスト」という手法が不可欠だ。このテストは、次のような手順で行われる。 まず、ユーザーA(例えばAlice)が自分のアカウントでAPIを通じてリソース(請求書など)を作成する。 次に、ユーザーB(例えばBob)がユーザーAが作成したそのリソースにアクセスしようと試みる。 もしユーザーBがアクセスに成功してしまったら、そこに認可の欠陥がある、つまりBOLA脆弱性があるということだ。 さらに、「A-B-Aテスト」というバリエーションもある。これは、ユーザーBがユーザーAのリソースを削除しようと試み、その後、ユーザーAが自分のリソースがまだ無事であることを確認するというテストだ。
A-Bテストを行う上で、APIのレスポンスコードも重要になる。ユーザーBが他人のリソースにアクセスしようとした場合、APIは「404 Not Found(見つかりません)」というレスポンスを返すのが理想だ。なぜなら、「404」を返せば、ユーザーBはそのリソースが「存在しない」のか、あるいは「存在はするが自分にはアクセス権がない」のかを区別できないからだ。これにより、攻撃者が存在するリソースのIDを一つずつ特定するのを防ぐことができる。もし「403 Forbidden(禁止されています)」というレスポンスを返すと、リソースの存在を攻撃者に教えてしまうことになるため、データがユーザーに紐づくような場合は「404」が推奨される。ただし、ユーザーが既にリソースの存在を知っていて、単に削除権限がない場合は「403」が適切だ。
BOLAの修正自体は、通常たった1行のコードで実現できるほどシンプルだが、そのシンプルさゆえに、開発時に忘れられがちだ。基本的な修正原則は、「オブジェクトをIDだけで検索せず、常に『IDとその所有者ID』の両方を条件に検索する」ことである。データベースで言えば、「WHERE id = $1 AND owner_id = $2」という条件でデータを取得するイメージだ。Go言語での実装では、ログイン中のユーザーIDとリクエストされたオブジェクトIDを使ってデータベースからデータを検索する関数を呼び出す。この関数自体が、IDと所有者IDの両方をチェックするようになっているため、開発者が所有者チェックをうっかり忘れても、コンパイルエラーでミスを防ぐことができる。これは「後でチェックする」のではなく、「取得時に所有者をフィルタリングする」堅牢なアプローチだ。
SymfonyのようなPHPフレームワークでは、「Voter」という機能を使って認可ロジックを実装できる。Voterは「このユーザーはこのリソースを閲覧できるか?」という問いに対して「はい」か「いいえ」を返す役割を担う。APIのルートにVoterを適用し、リソースの所有者IDとログイン中のユーザーIDを比較して、一致しない場合は「404」を返すように設定する。Symfonyのアプローチは、まずオブジェクトをIDで取得してからVoterで所有者チェックを行うため、「後でチェックする」方式に近いが、認可ロジックが一箇所に集約され管理しやすい。
どちらの実装においても、A-Bテストの自動化は極めて重要だ。Go言語の例では、httptestパッケージを使ってAPI全体を起動し、Aliceが請求書を作成し、Alice自身がその請求書にアクセスできることを確認した後、Bobが同じ請求書にアクセスして「404」が返されることを検証する。もし「200」が返されたら、テストは失敗し、BOLA脆弱性があることを開発者に知らせる。テストの信頼性を確保するためには、わざと修正コードを無効にしてテストが失敗することを確認する「破壊テスト」も行われる。
コードレビューは開発プロセスにおいて重要だが、BOLAのような1行の修正、あるいは1行の漏れといった単純なミスは、人間が見落としやすい。また、一度修正されても、将来のコード変更で新たなAPIルートが追加されたりする際に、再び脆弱性が混入するリスクは常にある。 だからこそ、「報告書は一度読まれるが、テストはコミットごとに実行される」という言葉が示すように、自動化されたA-Bテストは極めて有効な対策となる。新しいAPIルートが追加されるたびに、そのルートに対してA-Bテストを記述し、変更や削除を伴う場合はA-B-Aテストも追加することで、継続的にセキュリティを確保できる。
結論として、BOLAがAPI脆弱性のトップに位置するのは、その検出の難しさにある。他人のリソースにアクセスしても「200 OK」のような正常なレスポンスが返ってくるため、単一のレスポンスを見ただけでは問題を発見できない。問題の本質は、「誰が」リクエストしているのか、つまり「誰がこのリソースの所有者なのか」という点にある。A-Bテストは、二つのアカウントを使ってこの核心的な問いを検証し、APIの認可の欠陥を確実に浮き彫りにする、強力なセキュリティ対策である。システムエンジニアを目指す皆さんには、このBOLA脆弱性の理解と、A-Bテストの導入が、堅牢なシステム構築のために不可欠な知識となるだろう。