Idcon 17th ritou OAuth 2.0 CSRF Protection

Preview:

DESCRIPTION

#idcon 17thで発表した内容に2つの内容が含まれていましたが、これはOAuth 2.0のCSRF対策の部分だけを抜き出したものです。

Citation preview

OAuth2.0のCSRF対策拡張を

考えて導入した話

Ryo Ito(@ritou)

2013/11/29

#idcon Vol.17

#idcon vol.17 1

本発表の内容

• “OAuthのセキュリティ強化を目的とする拡張仕様を導入しました”

– http://alpha.mixi.co.jp/2013/12020/

#idcon vol.17 2

CSRF

(Cross Site Request Forgeries)

#idcon vol.17 3

CSRF脆弱性を持つ

日記投稿サービス

• ユーザー認証機能あり

• 投稿フォームからPOSTリクエストにより日記コンテンツをWebサーバーに送信

• Webサーバーは受け取ったコンテンツをログイン中のユーザーの日記として保存、公開

#idcon vol.17 4

日記投稿サービス

に対するCSRF例

#idcon vol.17 5

ユーザーA

日記投稿サービス

悪意のあるサービス 1. 悪意のあるサービスに誘導される

(spamメール、メッセージ、攻撃者が

投稿した日記の中のリンクなどから)

2. 悪意のあるサービスが

日記投稿サービスにリクエストを送る

3. 日記投稿サービスは、悪意のあるサービスからのリクエストをユーザーAの投稿として処理

リスク

• ユーザーが意図しない投稿をされるおそれ

• 投稿された日記に悪意のあるサービスへの誘導用リンクが入っていたら、次から次へと...

#idcon vol.17 6

日記投稿サービスがとるべき

CSRF対策

• セッションIDを投稿フォームのhiddenパラメータに含む

–攻撃者は第3者のセッションIDを知らない

• リクエストを受け取ったら、セッションIDの値を検証する

#idcon vol.17 7

日記投稿サービスがとるべき

CSRF対策

#idcon vol.17 8

ユーザーA

日記投稿サービス

悪意のあるサービス

2. 悪意のあるサービスが

日記投稿サービスにリクエストを送る

3. 日記投稿サービスは、リクエスト中のセッションIDとユーザーAのセッションを検証し、不正なリクエストをブロック!

1. 悪意のあるサービスに誘導される

(spamメール、メッセージ、攻撃者が

投稿した日記の中のリンクなどから)

CSRF脆弱性を持つ

ログインサーバー

• ログインフォームからPOSTリクエストによりID/パスワードをWebサーバーに送信

• Webサーバーは受け取ったID/パスワードを検証し、有効な組み合わせであればログイン処理を行う

#idcon vol.17 9

ログインサーバー

に対するCSRF例

#idcon vol.17 10

ユーザーA

ログインサーバー

悪意のあるサービス 1. 悪意のあるサービスに誘導

2. 悪意のあるサービスが

ログインサーバーに攻撃者の

ID/PWを送る

3. ログインサーバーは、

悪意のあるサービスからのリクエストを

ユーザーAのログイン試行として処理

リスク

• 攻撃者のアカウントとしてログインさせられてしまう

• その後、気付かずに保存したデータなどに攻撃者からアクセスされる可能性

–プライベートな画像

–住所情報

– クレジットカード情報など

#idcon vol.17 11

ログインサーバーがとるべき

CSRF対策も同じ

• セッションIDをログインフォームのhiddenパラメータに含む

–攻撃者は第3者のセッションIDを知らない

• リクエストを受け取ったら、セッションIDの値を検証する

#idcon vol.17 12

ここまでは一般的な話

• Web Application Frameworkで対策されているものもある

#idcon vol.17 13

OAuth 2.0とCSRF

• 認可フローにおけるCSRFのリスクとは

• まずは認可フローの復習から

#idcon vol.17 14

ユーザーA Client Server

OAuth 2.0の認可フロー

0. 認可処理開始

1. 認可要求

2. リソースアクセスを許可

3. 認可応答

認可コード

4.アクセストークン

取得

認可コード

アクセストークン

ユーザーAの

セッションに紐付く

15

OAuth 2.0におけるCSRF

• 第3者(もしくは第3者のセッション)に攻撃者のアクセストークンを紐づけさせようとする攻撃

• 標的となるユーザーのセッション上で自らの認可応答をClientに渡す

#idcon vol.17 16

ユーザーA Client Server

OAuth 2.0の認可フローにおけるCSRF

0. 認可処理開始

1. 認可要求

2. リソースアクセスを許可

3. 認可応答

4.アクセストークン

取得

認可コード

アクセストークン

ユーザーB

認可コード

ユーザーAの

アクセストークンが

ユーザーBの

セッションに紐付く

認可応答を

ユーザーBのセッションで

処理させる

17

攻撃者 標的

リスクはログインのCSRFと同等

• その後のAPIアクセスで取り扱われるデータはServerにとっては攻撃者のものとなる

• OAuthを認証に使っている場合は攻撃者にアカウントを乗っ取られる可能性もある

• 攻撃者としては認可応答のURLを他人のブラウザで実行されるだけでよい

#idcon vol.17 18

stateパラメータによる対策

• Clientがセッションに紐づくstateパラメータを生成

• Clientがstateパラメータを認可要求に指定

• Serverが認可応答にstateパラメータを指定

• Clientがstateパラメータとセッションの整合性を検証してからトークンを取得する

#idcon vol.17 19

ユーザーA Client Server

OAuth 2.0の認可フロー(stateパラメータあり)

0. 認可処理開始

1. 認可要求

2. リソースアクセスを許可

3. 認可応答

4.アクセストークン

取得

認可コード

アクセストークン

state

ユーザーAのセッションに

紐付くstateを

払い出す

stateがユーザーAの

セッションに紐づくことを

検証 -> 成功

認可コード state

認可要求に

含まれるstateを

そのまま指定

20

ユーザーA Client Server

OAuth 2.0の認可フローにおけるCSRF (stateパラメータあり)

0. 認可処理開始

1. 認可要求

2. リソースアクセスを許可

3. 認可応答

ユーザーB

認可コード

state

state

ユーザーAのセッションに

紐付くstateを

払い出す

stateが

ユーザーBのセッションに

紐づくことを

検証 -> 失敗

認可応答を

ユーザーBのセッションで

処理させる

21

攻撃者 標的

Clientの実装に依存

• Clientがセッションに紐づくstateパラメータを生成

• Clientがstateパラメータを認可要求に指定

• Serverが認可応答にstateパラメータを指定

• Clientがstateパラメータとセッションの整合性を検証してからトークンを取得する

#idcon vol.17 22

Clientの実装をどう信用するか

• 認可要求にstateパラメータつけないかも

• 認可要求にstateパラメータがついてきても、セッションに関係しない値を利用してるかも

• 認可要求にstateパラメータがついてきても、認可応答の値を検証してないかも

これらをServer側で動的に確認することは困難

#idcon vol.17 23

Server側で対策をとれる拡張

• Serverがserver_stateパラメータを生成

• Clientがserver_stateパラメータをセッションに紐づけ、認可要求に指定

• Serverが認可コードにserver_stateパラメータを紐付け、認可応答には含まない

• Clientはセッションに紐づくserver_stateを認可コードとともに送り、トークンを要求する

• Serverは認可コードとserver_stateを検証

#idcon vol.17 24

ユーザーA Client Server

OAuth 2.0の認可フロー(server_stateパラメータあり)

0. 認可処理開始

2. 認可要求

3. リソースアクセスを許可

4. 認可応答

認可コード 5.アクセストークン

取得

認可コード

アクセストークン

server_state

1. server_state取得

server_state

server_state

セッションと

server_stateを

紐付け

セッションと紐づくserver_state

を指定

認可コードと

server_stateを

紐付け

認可コードと

server_stateの

検証に成功

25

ユーザーA Client Server

OAuth 2.0の認可フローにおけるCSRF (server_stateパラメータあり)

4. 認可応答

ユーザーB

認可コード 5.アクセストークン

取得

認可コード

server_state

3. リソースアクセスを許可

0. 認可処理開始

2. 認可要求

server_state

1. server_state取得

server_state

セッションと

server_stateを

紐付け

認可応答を

ユーザーBのセッションで

処理させる

ユーザーBの

セッションと紐づくserver_state

を指定

26

認可コードと

server_stateの

検証に失敗

攻撃者 標的

ポイント

• Clientが実装を省略できない

– server_stateをセッションと紐付けて管理しなければアクセストークンを取得できない

#idcon vol.17 27

ネイティブアプリへの適用

• Client Credentialが安全に管理できない状況における”認可応答の奪取”の問題

– redirect_uriを被せて認可応答を受け取る手口

• Authorization Code Grant + server_stateを利用することで、認可要求を作成したClient

のみがトークンを取得できる

– Client Secretは空でよい

#idcon vol.17 28

割愛

導入状況

• OAuth 2.0の認可を利用するしくみに導入

– mixi Graph API/mixiアプリ/mixiページアプリ

• 既存のClientへの影響から、server_stateパラメータの利用は任意

• API(scope)単位で必須化を検討中

–お金や大事な情報を扱うAPIへの認可

–認証連携のためのAPIへの認可

#idcon vol.17 29

まとめ

• 既存のstateパラメータによる対策に課題を感じていた

• server_stateを用いた拡張を導入した

• この拡張の利用はOpenID Connect用のscopeなどで必須化したい

#idcon vol.17 30

終わり

• Ryo Ito (@ritou)

• 株式会社ミクシィ

• OIDF-J エヴァンジェリスト : http://openid.or.jp/

• Blog : http://d.hatena.ne.jp/ritou/

• Gihthub : https://github.com/ritou

#idcon vol.17 31

Recommended