「自分の鍵で他人の家に入れる?」Webアプリの致命的な盲点、IDORを攻略しよう
こんにちは。セキュリティの現場で日々、複雑な攻撃と対峙していると、時々「基本中の基本」が一番恐ろしい事態を招いていることに気づかされます。
今日お話しするのは、IDOR(Insecure Direct Object Reference:不適切なオブジェクト参照)という厄介なやつです。名前は難しそうですが、仕組みはとてもシンプル。そして、多くの開発現場で見落とされている「盲点」です。
初心者の方にもわかりやすく、身近な例えから紐解いていきましょう。
—
1. IDORって何?「泥棒」に例えるとこうなる
想像してみてください。あなたは今、とあるマンション(Webアプリ)の住人です。自分の部屋番号は「101号室」で、鍵を持っていますよね。
ここで、もしあなたが「URLの数字を101から102に変えたら、隣の部屋が開いちゃった」としたらどうでしょう? 鍵を確認されることもなく、他人の部屋にスッと入れてしまう。これがIDORという攻撃の正体です。
Webの世界では、以下のようなURLがよくあります。
`https://example.com/api/user/101/profile`
攻撃者は、「101」という数字を「102」「103」…と書き換えて、他のユーザーの個人情報を盗み見しようとします。サーバー側が「このリクエストを送ってきたのは本当に101号室の住人か?」という確認をサボっていると、簡単に侵入を許してしまうのです。
—
2. なぜ防げないのか?「性善説」という落とし穴
多くのエンジニアがやってしまうのが、「ログインしているから大丈夫だろう」という思い込みです。
ログインしている=「このマンションの住人である」ことは証明されています。でも、「自分がどの部屋の鍵を持っているか」までは、システムが厳密にチェックしていないことが多いのです。
ダメな実装例(認可の欠如)
「ログイン済みユーザーなら、誰のプロフィールでも見せちゃえ!」というコードは、非常に危険です。
// 危険なコード:ログインチェックはしているが、所有権の確認がない
app.get(‘/api/user/:id/profile’, authenticateToken, (req, res) => {
const userId = req.params.id; // URLのIDをそのまま信じて取得
const user = db.query(‘SELECT FROM users WHERE id = ?’, [userId]);
res.json(user); // 誰のIDでも取得できてしまう!
});
—
3. 泥臭く守る:認可ロジックの集中管理
では、どうすればいいのでしょうか? 答えは「ゲートキーパーを置くこと」です。
一つ一つの機能で「この人は本人か?」と確認するのは大変ですし、書き忘れも発生します。そこで、認可ロジックを共通化(集中管理)するのが鉄則です。
安全な実装の考え方
「URLのID」と「ログイン中のユーザーID(セッション情報)」を必ず照らし合わせる仕組みを作りましょう。
// 安全なコード:所有権を確認してからデータを出す
app.get(‘/api/user/:id/profile’, authenticateToken, (req, res) => {
const requestedId = req.params.id;
const currentUserId = req.user.id; // ログイン中のユーザーID(改ざん不可なトークンから取得)
// 【重要】URLのIDと、ログイン中の自分のIDが一致するかチェック!
if (requestedId !== currentUserId) {
return res.status(403).json({ error: “ダメです!他人のデータは見られません。” });
}
const user = db.query(‘SELECT FROM users WHERE id = ?’, [requestedId]);
res.json(user);
});
—
4. 開発現場で今すぐできるテスト手法
「自分のコードは大丈夫かな?」と不安になったら、まずは「なりすましテスト」を自分で行ってみてください。
1. ブラウザを2つ開く: アカウントAとアカウントBを用意します。
2. IDの入れ替え: アカウントAでログインした状態で、ブラウザのURLを `…/user/BのID/profile` に書き換えてみます。
3. 確認: 「403 Forbidden(アクセス拒否)」や「401 Unauthorized」が返ってくれば合格です! もしデータが表示されてしまったら…すぐに修正しましょう。
—
最後に:セキュリティは「疑うこと」から始まる
セキュリティ対策とは、「ユーザーはURLを書き換えるかもしれない」「ブラウザのデベロッパーツールを操作するかもしれない」という前提に立つことです。
「そんな悪いことする人はいないよね?」という性善説は、残念ながらWebの世界では通用しません。でも、一度「サーバー側で最後にもう一度チェックする」という癖を身につければ、あなたの作るアプリケーションは格段に強固になります。
最初から完璧を目指す必要はありません。まずは自分のコードの中に、「このデータは、本当にこの人が見ていいものか?」と自問するポイントを一つ作ることから始めてみてください。一歩ずつ、一緒に守りを固めていきましょう!

コメント