Open17

Authメモ

SenkSenk

OAuth2.0についての諸考察を書きます

SenkSenk

PKCE(pixyと発音するらしい)はOAuth2.0のトークン付与方式のうち、最も基本的なAuthorization Code Flowを認可コード横取り攻撃から守るための仕様である。これは以下のパラメータから定義される。

  • code_verifier 43文字〜128文字のURLセーフな文字
  • code_challenge code_verifierをsha256でハッシュ化した値
  • code_challenge_method(S256かplain)

https://www.authlete.com/ja/developers/pkce/

SenkSenk

以下の手順で行う

  1. クライアントはcode_verifierを算出し、code_challengeも算出する
  2. 認可エンドポイントへのリクエスト時、サーバはクエリパラメータからcode_challengeとcode_challenge_methodを受け取り、記録する
  3. クライアントは認可コードをリダイレクトで受け取り、トークンエンドポイントへのリクエストボディにcode_verifierを含める
  4. サーバーは記録したcode_challengeとcode_challenge_method、送られてきたcode_verifierを使い、code_challenge=sha256(code_challenge)を確認する。

code_challengeとcode_verifierが存在しない場合、認可リクエストを送ったクライアントと認可コードを使ってトークンエンドポイントにリクエストしたクライアントが同じであることを保証できない。例えば、リダイレクト先に悪意あるアプリが指定されていた場合、悪意あるアプリは認可コードを取得してアクセストークンを取得できてしまう。

SenkSenk

OAuth2.0とは?

SenkSenk

OAuthは認可のフレームワークです。サードパーティアプリケーションがリソースオーナーの所有するProtected Resourceへの部分的または全体のアクセス権を獲得する「認可」を可能にします。OAuthには以下のようなアクターが存在しています。

  • Resource Owner APIへのアクセス権を持つ人。
  • Protected Resource リソースオーナーがアクセス権を持つリソース
  • Client リソースオーナーの代わりにAPIを利用する全てのソフトウェア
  • Authorization Server トークンの発行や認可を行うサーバ

クライアントはClient Secretを持つクライアント(Confidential Client)であることを期待します。Confidential Clientとはパスワードなどのクレデンシャルを持つクライアントのことです。

SenkSenk

基本的な認証手順での方法は次のようになります。

  1. リソースオーナーからクライアントにアクセスがあったらリソースオーナーのブラウザを認可サーバにリダイレクトさせ、GETを送らせる。
  2. 認可サーバはリソースオーナーをクレデンシャルによって認証する。リソースオーナーの認証情報は認可サーバのみが知っている。
  3. リソースオーナーはクライアントを認可する。この認可情報は認可サーバが保持し、次回アクセス時にも利用する。認証情報は保持しない。
  4. 認可サーバはレスポンスによってリソースオーナーをリダイレクトさせる。リダイレクト先のURIには認可コード(ワンタイムのクレデンシャル)をクエリとして送る。
  5. クライアントは認可サーバに認可コードとクレデンシャルを送り、Basic認証を行う。クレデンシャルによって、最初にリクエストがあったクライアントであることを確認し、認可コードによって認可された権限を確認する。
  6. 認証に成功したら、トークンをクライアントに送る。これはJSONとして返される。このJSONにはトークンとトークンタイプの他、スコープや有効期限、リフレッシュトークンが含められる。
  7. トークンを提示する。Authorizationヘッダに含めるなどする。
SenkSenk

PKCEとは??

SenkSenk
  • Bot Confidential Client Authorization Codeを利用
  • Web App Confidential Client Authorization Codeを利用
  • Native App Public Client Authorization Codeを利用 (PKCEを利用)
  • SPA Public Client Implicitを利用
SenkSenk

PKCEとは

PKCE(pixyと発音するらしい)はOAuth2.0のトークン付与方式のうち、最も基本的なAuthorization Code Flowを認可コード横取り攻撃から守ることが可能なAuthorization Code Flowである。
主にPKCEが保護するのはネイティブアプリだが、Authorization Code Flow with PKCEは4つのクライアントを全てサポートする。

SenkSenk

認可コード横取り攻撃(ネイティブアプリ)

認可コードはClient Secretを持つクライアントの場合、横取りされたとしても大きな問題はない。しかし、Public Clientの場合、Client Secretを持たないので、その認可コードは誰にでも利用できてしまう。

Public Clientのうち、ネイティブアプリはURIフラグメントを利用するImplicitフローを使うことが難しいため、認可コードフローを利用する。しかし、これには問題がある。
ネイティブアプリはその性質上、ブラウザを使うとは限らないので、リダイレクト先を指定に工夫が必要である。多くの場合は、カスタムURIスキームを利用してブラウザからネイティブアプリに遷移させることで認可コードを受け取るようにしていた。

だが、リダイレクト先は公開情報であり、誰でも登録することが可能である。これを利用してリダイレクト先を悪意あるアプリに向けることで認可コードを奪取することができてしまう。(要調査)

この攻撃を防ぐために二つの方法がある。

  1. カスタムURIスキームをドメイン名の逆順にする
  2. PKCEを利用する。

PKCEについて解説する。

SenkSenk

Authorization Code With PKCE

Authorization Code With PKCEはこの攻撃を防ぐための使用である。フロントチャネルとバックチャネルのクライアントのリクエストを以下のパラメータで結びつけることで、なりすましを許さない。

  • code_verifier 43文字〜128文字のURLセーフな文字
  • code_challenge code_verifierをsha256でハッシュ化した値
  • code_challenge_method(S256かplain)
SenkSenk

Authorization Code With PKCE をネイティブアプリで

以下が参考になる。

https://datatracker.ietf.org/doc/html/rfc8252

ネイティブアプリでAuthorization Code Flowを使う場合、特定のプラットフォームでのアプリなどを除いて、Client Secretを使わずにバックチャネルでの認証を行わないといけない(MUST)。Client SecretはAuthorization Code Flowでなくてはならないパラメータではない(Credentials Flowでは必須)。

OAuthはこの認証方法について定義しておらず、プロバイダに任せているようである。(要調査)
ただ、Basic認証を使ってもよいということだけは示唆されている。
https://openid-foundation-japan.github.io/rfc6749.ja.html#client-password

ツイッターではアプリの登録時にどのタイプのアプリか設定させた上でclient idを発行することで、client idによってBasic認証を実施するかどうかを判別しているみたい。

SenkSenk

SAMLについて

SenkSenk

SAMLエンティティ

  • OP(OpenID Provider)

  • SP(Service Provider)

  • IdP(Identity Provider)

  • RP(Relying Party)

  • Relying Party SAMLアサーションを使用するパーティ

  • Asserting party(SAML Authority) はSAMLアサーションを作成するパーティ

  • SAML responderはSAMLアサーションの要求に応じるエンティティ

  • SAML requesterはSAMLアサーションの要求をするエンティティである。

SAML

SAML(Security Assertion Markup Language)はユーザーの権限などをXML形式で記述した文書。SAMLは「IDがAのユーザーがメールアドレスBでログインし、本システムで認証されている」といったような情報を伝える役割を持つ。

Assertion(アサーション)

OAuthのAssertion Grant TypeではAssertionと呼ばれる暗号的に保護された証明書を使って認可を行う。このGrant TypeClient Credentialsとは異なり、クレデンシャルであるアサーションがユーザーの権限を定義している。

SAMLのユースケースと解決する課題

SAMLの用途は主に3つある。

  1. SSO SAMLはユーザー情報をIdPとSPのマルチドメインで受け渡すことを可能にし、SSOを実現する。
  2. Federated Identity 特定サービスでのみ有効なID(Local ID)を、複数のサービス間でも識別可能なID(Federated)にする。
  3. アサーション アサーションの業界標準として機能する。SAMLはSAML標準のプロトコル以外でも使用してよい。

Federated Identity

ユーザーを一意に識別するIDに対して、複数のプロバイダ間で連携がある場合に、IDがFederatedであると言われる。

  1. ログインがないSPに対してアクセスがあった場合、IdPにリダイレクトさせる。
  2. IdPに同意し、Federated Identityを生成する。IdPはこのFederated IdentityでログインしていることをSAMLを送ることでSPに伝える。
  3. SPはFederated IdentifierとローカルのIDを結びつけて使用する。

MDSSO

SAMLの主なユースケースはIdPとSPでのSSOである。SAMLが実現するSSOは二種類ある。ここで、IdPとSPがFederated Identity(ID連携)を持ち、SPはIdPを信頼するとする。

  • IdP-initiated web SSO IdPで認証したデータ(Security Context)をSAMLでSPに送ることで、SPでも認証される。
  • SP-initiated web SSO SPのProtected Resourceへのアクセス時に、IdPへのSAML認証を要求する。

SPはIdPを信頼しており、Federated IdentityによってIdPとSPのLocal IDが結びついているので、IdPがSAMLによって認証情報を表明することで、SPでの再認証を省略する。