「鍵を全部渡してない?」OAuth 2.0のスコープで守る、あなたのアプリの「裏口」
こんにちは。セキュリティの世界で泥臭いインシデントと戦い続けているエンジニアです。
今日は「OAuth 2.0のスコープ」という、一見すると地味だけど実はめちゃくちゃ重要な話をします。「ログイン機能なんてフレームワークにお任せでしょ?」と思っているあなた。その油断が、実は攻撃者にとって最高の「招待状」になっているかもしれません。
家で例えるなら、「ちょっと郵便物を見ておいてほしいだけ」と隣人に頼むときに、家中の鍵を全部渡してしまっているような状態。これが、権限を絞り込めていないOAuthの怖いところなんです。
—
そもそも「スコープ」って何者?
OAuth 2.0において「スコープ」とは、一言で言えば「そのアプリに何ができるか」という権限のリストです。
GoogleやTwitter(X)でログインするとき、「このアプリがあなたのプロフィール情報にアクセスすることを許可しますか?」といった画面が出ますよね。あれがまさに「スコープ」の提示です。
- 良い例: 「メールアドレスだけ教えてね」
- 悪い例: 「メールアドレス、連絡先、Googleドライブの全ファイル、投稿の代行まで全部やらせてね!」
もし、あなたが作ったアプリが後者のような過剰な権限(これを「過剰スコープ」と呼びます)を要求していたら、あなたのアプリが何らかの理由で乗っ取られた瞬間、ユーザーのGoogleドライブの中身まで全て泥棒に差し出すことになります。
—
攻撃者は「同意画面」の隙を狙う
攻撃者は、わざわざ高度なハッキング技術を使いません。一番楽なのは「ユーザー自身に、自分たちのアプリに鍵を渡してもらうこと」です。
もしあなたがアプリを開発する際、面倒くさがって「とりあえず全権限(`all_access`のような広範なスコープ)」を要求する設定にしていたとします。ユーザーは同意画面で「おっ、何か色々アクセスするアプリだな」と不安に思いつつも、使うためにOKを押してしまいます。
ここで攻撃者があなたのアプリの脆弱性を突き、アクセストークンを盗み出せば、そのユーザーのGoogleドライブやメールは攻撃者のやりたい放題。「最小権限の原則(Principle of Least Privilege)」を守ることは、ユーザーを守る盾そのものなんです。
—
実践:最小権限で設計しよう
では、どうやって対策すればいいのでしょうか。開発現場で今日からできる「絞り込み」の考え方を見ていきましょう。
1. 必要なもの以外は書かない
例えば、ユーザーのメールアドレスだけが必要なら、`profile`や`email`といった必要最小限のスコープだけを指定します。
悪い例(とりあえず全部入り):
危険!必要以上に権限を要求してはいけません
scope=openid profile email drive.readonly drive.file gmail.modify
良い例(絞り込む):
これだけで十分なら、これ以上は指定しない
scope=openid email
2. 同意画面での「透明性」を意識する
ユーザーが「このアプリ、なんで私の連絡先を読み込もうとするの?」と疑問に思ったら、それは設計ミスです。
UI上で「この機能にはこの権限が必要です」と説明を表示し、納得してもらった上でスコープを要求する。この「納得感」こそがセキュリティの基本です。
3. リクエストパラメータで制御する(コード例)
OAuthのフローを呼び出す際、プログラム側では以下のようにスコープを最小限に絞ってリクエストを送ります。
// 認証リクエストを構築する際の例
const authUrl = new URL(‘https://accounts.google.com/o/oauth2/v2/auth’);
authUrl.searchParams.append(‘client_id’, ‘YOUR_CLIENT_ID’);
authUrl.searchParams.append(‘response_type’, ‘code’);
authUrl.searchParams.append(‘redirect_uri’, ‘https://your-app.com/callback’);
// ここが重要!本当に必要な権限のみをスペース区切りで指定する
// 「メールアドレス」と「プロフィール」のみに限定
authUrl.searchParams.append(‘scope’, ‘openid email profile’);
// ユーザーにはこのURLへアクセスしてもらう
console.log(authUrl.toString());
—
最後に:セキュリティは「信頼の積み重ね」
新人の皆さんにとって、セキュリティ対策は「面倒なルール」に見えるかもしれません。でも、想像してみてください。あなたが作ったアプリで、ユーザーの大切なデータが流出したとき、誰が一番傷つくか。それは、あなたを信じて「OK」ボタンを押してくれたユーザーです。
「最小権限の原則」を守ることは、単なる技術的な作法ではありません。「私はあなたの大切な情報を、必要以上に奪うことはしませんよ」という、ユーザーへの誠実なメッセージなんです。
今日からコードを書くとき、ふと手を止めて考えてみてください。
「このスコープ、本当に全部必要かな?」
その小さな問いかけが、あなたのアプリを世界で一番安全な場所にしていくはずです。一歩ずつ、一緒に学んでいきましょう!

コメント