トークンを適切に無効化することはセキュリティの面において非常に重要です。ただ、OAuth 2.0 の仕様を読むと、こういう時にはトークンを無効化すべきだ、と書かれている箇所が何箇所もあって難しいなと感じたので、まとめてみました。
(まとめてみると意外とシンプルでした😊)
トークンを無効化するタイミング
- クライアントからトークンの取り消しの要求があったとき
- リソースオーナーから認可の取り消しの要求があったとき
- トークンの有効期限が切れたとき
- リフレッシュトークンが更新されたとき
- 古いリフレッシュトークンが使用されたとき
- 認可コードが2度以上使用されたとき
- クライアントシークレットを無効化するとき
クライアントからトークンの取り消しの要求があったとき
エンドユーザーがログアウトするときやアカウントの切り替えを行う時など、クライアントにとってトークンが必要なくなったときには、トークンの無効化を行うのがよいとされています。理由は、不要になったアクセストークンの乱用防止やユーザーからの信頼につながるためです。
そのため、OAuth 2.0 Token Revocation には、以下のようにトークン無効化のエンドポイントを用意するよう記載されています。
実装はリフレッシュトークンの無効化はサポートしなければならなく(MUST)、アクセストークンの無効化はサポートすべきである(SHOULD)。
また、無効化の際には関連するトークンや認可自体の無効化についても検討する必要があります。
- 特定のトークンを無効化するときは、関連したトークンとその元となる認可の無効化を行ってもよい(MAY)
- リフレッシュトークンを無効化するときは、アクセストークンも無効化すべきである(SHOULD)
- アクセストークンを無効化するときは、リフレッシュトークンを無効化してもよい(MAY)
リソースオーナーから認可の取り消しの要求があったとき
リソースオーナーは上記の「トークン無効化エンドポイント」の仕組みとは別に認可を無効化してよいです。OAuth 2.0の仕様には明示的には記載されていませんが、認可を無効化する際には、リフレッシュトークン、アクセストークンもセットで無効化するべきでしょう。
トークンの有効期限が切れたとき
トークンには有効期限が設定されます。アクセストークンの有効期限は短く、リフレッシュトークンの有効期限は長めに設定されます。有効期限切れのトークンを用いたリクエストは拒否されるようにすることで、明示的な無効化の処理なしにトークンの無効化を実現できます。
リフレッシュトークンが更新されたとき
リフレッシュトークンが更新されたときには、古いリフレッシュトークンを無効化してもよいです(MAY)。必須でない理由は、古いリフレッシュトークンが使用された場合にはトークンを無効化することでセキュリティ上の危険を防ぐことができるためです。
ちなみに、新しいリフレッシュトークンが発行された場合、クライアントは古いリフレッシュトークンを破棄し、新しいリフレッシュトークンを使用しなければいけません (MUST).
古いリフレッシュトークンが使用されたとき
上記の「リフレッシュトークンが更新されたとき」に関連しますが、古いリフレッシュトークンを用いたリクエストがあった場合は、リフレッシュトークンが盗まれた可能性があります。認可サーバー側からは攻撃者と正当なクライアントのどちらがアクセスしようとしているのか判断できないため、有効なリフレッシュトークンとそれに関連するアクセストークン全てを無効化する必要があります。
認可コードが2度以上使用されたとき
仕様には以下のように記載されています。
もし認可コードが2回以上使用された場合は, 認可サーバーはリクエストを拒否しなければならず (MUST), この認可コードを基に発行されたこれまでのすべてのトークンを無効化すべきである (SHOULD).
認可コードが2度以上使用された場合は認可コードが盗まれている可能性があるとみなし、「古いリフレッシュトークンが使用されたとき」と同様にトークンの無効化を行う必要があります。
そのため、クライアントは2回以上認可コードを使用してはいけません(MUST NOT)。
クライアントシークレットを無効化するとき
シークレットの漏洩がわかった時などは、悪用を防止するためシークレットを無効化する必要があります。このときは、発行したリフレッシュトークンやアクセストークンも全て無効化すべきでしょう。
まとめ
無効化タイミング | 重要度 |
---|---|
クライアントからトークンの取り消しの要求があったとき | リフレッシュトークンの無効化のサポート: MUST アクセストークンの無効化のサポート: SHOULD 認可自体の無効化 : MAY |
リソースオーナーから認可の取り消しの要求があったとき | 認可取り消しに伴うリフレッシュトークンの無効化: SHOULD 認可取り消しに伴うアクセストークンの無効化: SHOULD |
トークンの有効期限が切れたとき | 有効期限切れのトークンの無効化: MUST |
リフレッシュトークンが更新されたとき | リフレッシュトークンの無効化: MAY |
古いリフレッシュトークンが使用されたとき | リフレッシュトークンの無効化: SHOULD 関連するアクセストークンの無効化: SHOULD |
認可コードが2度以上使用されたとき | 認可コードを元に発行された全てのトークンの無効化: SHOULD |
クライアントシークレットを無効化するとき | リフレッシュトークンの無効化: SHOULD アクセストークンの無効化: SHOULD |
※ 仕様に明確な記載がない項目の重要度に関しては、筆者の考えで重要度を記載しています。間違っている箇所がありましたら、ご指摘いただけますと幸いです。