【入門編】APIにおけるBroken Object Level Authorization (BOLA) の検知と対策 – アプリケーションセキュリティ & 安全な開発防御ガイド

なぜ「鍵」をかけているのに泥棒が入るのか?APIの「BOLA」という盲点

こんにちは。セキュリティの世界へようこそ。
日々、開発の現場でコードを書いたり、インフラを整えたりしていると、「認証(ログイン)」さえしっかりしていれば大丈夫、と思ってしまいがちですよね。

でも、ちょっと想像してみてください。あなたは自分の家の玄関に最高級の鍵をかけました。合鍵を持っているのは家族だけ。完璧なセキュリティに見えますよね?

ところが、「リビングの窓」が全開で、しかも隣の家と繋がっていたらどうでしょう? 玄関の鍵なんて何の意味もありません。

今日お話しする「BOLA(Broken Object Level Authorization:オブジェクトレベルの認可不備)」とは、まさにこの「窓の閉め忘れ」のような、非常に恐ろしく、そして開発現場で最も見落とされやすい脆弱性の一つです。

—

泥棒は「ID」を推測する:BOLAのメカニズム

APIの世界で、BOLAは「IDの推測」から始まります。

例えば、あなたが自分のプロフィール情報を見るために、ブラウザからこんなリクエストを送るとします。
GET /api/users/123/profile

ここで「123」があなたのユーザーIDだとしますね。さて、悪意のある攻撃者はどう考えるでしょうか?
「123が自分なら、124や125は誰かのデータじゃないか?」

攻撃者はログインした状態で、わざと GET /api/users/124/profile というリクエストを投げます。もし、サーバー側が「ログインしているからOK!」としかチェックしていなかったら、他人の個人情報が丸見えになってしまいます。

これがBOLAの正体です。
「誰であるか(認証)」は確認しているのに、「そのデータにアクセスする権限があるか(認可)」を確認し忘れている。玄関の鍵は持っているけれど、他人の部屋に勝手に入り込める状態なのです。

—

防御の基本:ビジネスロジックで「所有権」を縛り上げる

BOLAを防ぐために、小難しいセキュリティツールを導入する前に、まずは「コードの書き方」から変えていく必要があります。

「ログインしているID」と「アクセスしようとしているデータの持ち主ID」が一致しているか。これを必ずビジネスロジック層で照合するのです。

悪いコード例(脆弱性あり)

// サーバーサイドの処理イメージ
app.get(‘/api/orders/:orderId’, (req, res) => {
// 単に「ログインしているか」しかチェックしていない
if (!req.user) return res.status(401).send(“ログインしてください”);

// IDだけでデータベースから注文情報を取ってきてしまう(危険!)
const order = db.orders.findById(req.params.orderId);
res.json(order);
});

良いコード例(対策済み)

app.get(‘/api/orders/:orderId’, (req, res) => {
if (!req.user) return res.status(401).send(“ログインしてください”);

// データベース検索時に「ログインユーザーのID」を条件に加える
// これにより、他人の注文IDを指定しても「見つからない」という結果になり安全
const order = db.orders.findOne({
id: req.params.orderId,
ownerUserId: req.user.id // ここで「所有者」を厳密に照合する
});

if (!order) return res.status(404).send(“注文が見つかりません”);
res.json(order);
});

—

「推測」をさらに難しくする:UUIDの活用

もしIDが 1, 2, 3... と連番になっていたら、攻撃者は非常に簡単にIDを推測できてしまいます。これを防ぐために、IDには推測不可能な「UUID(ユニバーサル一意識別子)」を使うのが現代の定石です。

  • 連番ID: 123 → 次は 124 だとバレる
  • UUID: 550e8400-e29b-41d4-a716-446655440000 → 推測するのはほぼ不可能

これだけで攻撃の難易度は跳ね上がります。もちろん、これだけで安心せず、先ほどの「所有権チェック」と併用するのが鉄則ですよ!

—

まとめ:セキュリティは「性悪説」で考えよう

「APIの利用者はみんな善良な人ばかり」と信じたい気持ちはよくわかります。でも、一度システムを公開すれば、そこはインターネットという名の荒野です。

1. 認証と認可は別物だと心得る: ログイン済み=何でも見られる、ではありません。
2. 所有権のチェックを徹底する: 「誰がアクセスしようとしているか」と「データの所有者は誰か」を毎回突き合わせましょう。
3. 推測可能なIDを避ける: UUIDを活用して、攻撃の入り口を絞りましょう。

セキュリティ対策は、一度やって終わりではありません。皆さんが書くコード一つひとつが、ユーザーを守る大切な「鍵」になります。最初は難しく感じるかもしれませんが、一歩ずつ、確実に理解を深めていきましょう。

何か不安なことや、「これってどうなの?」という疑問があれば、いつでもまた相談してくださいね。あなたのコードがより堅牢なものになることを応援しています!

コメント

タイトルとURLをコピーしました