Typekey認証(Ver.1.1)の基本的な仕組み。日本語の資料があんまり無い感じだったのでまとめてみました。 暗号とかセキュリティとかそーゆーの余り詳しくないので間違ってるかもしれませんすいませんごめんなさい。
MovableTypeに特化した話ではなく、Typekeyの認証の仕組み自体の説明。同様の仕組みを利用すれば MovableType、typekey.com以外でも再現可能。
認証を行わない更新可能なページの場合、
該当ページ --> 書込CGI --> 書込処理 --> 書込結果ページ
となりますが、TypeKey認証を行う場合、
該当ページ --> 書込CGI --> TypeKeyログインページ(typekey.com) --> 書込CGI --> 書込処理 --> 書込結果ページ
となります。要するに、一度、外部にあるTypeKey用のログインページに飛ばされて、認証に成功したら、元のCGIに戻ってきて 処理が続行される、と言う具合です。
TypeKey認証は認証が必要なサイト(クライアント)と実際に認証を行い、認証結果を返すサイト(サーバー)から構成されます。
クライアント - サーバー間の情報のやり取りは全てGET引数を用いて行います。
クライアントからサーバーに遷移する状態を「リクエスト時」、 認証後、サーバーからクライアントに遷移する状態を「レスポンス時」と表記します。
パラメータ名 | 説明 |
v | TypeKey認証のバージョン(1.1を設定) |
need_email | レスポンスにユーザーのメールアドレス情報を付加するか(1=付加する) |
t | 自サイトのトークン(TypeKey登録時に設定したもの) |
_return | 認証後に遷移するURL(基本的には現在のURL) |
パラメータ名 | 説明 |
ユーザーのメールアドレス、又はメールアドレスのハッシュ値(need_emailの場合のみ) | |
name | ユーザー名 |
nick | ユーザーのニックネーム(2バイト文字可能。UTF-8でURLEncodeされている) |
ts | 認証された日時 |
sig | GET引数の各値が改竄されていない事を保障するための文字列 |
事前準備として自サイト用のトークンを作成しておく。
つまり、自サイトのURLをサーバー側に事前に登録しておく必要があります。 トークンは本来はサイト情報と結びつくものであり、ユーザーとは直接的に関係ありませんが、 typekey.com では、サイト、トークンをユーザーとも結び付けている(ユーザー情報の1つとして捉えている)為、 トークンを取得するためには、まず自分自身がTypeKeyユーザーになる必要があります。
リクエスト時のGET引数、レスポンス時のGET引数は「GET引数仕様」を参照。
コメント等の何らかページの更新が起こるような仕組みがある場合、そのPOST先のscript内で、以下のような処理を行う。
事前準備として、
が必要。又、当然、ログインするユーザーがユーザーDBに登録されている必要がある。
リクエスト時のGET引数、レスポンス時のGET引数は「GET引数仕様」を参照。
認証サーバーとクライアントが全く別ドメインで独立して存在している為、 サーバー - クライアント間でのセッション情報共有みたいな事は 一切行っていません。
しかも、サーバーへのリクエスト情報、サーバーからのレスポンス情報も全てURLのGET引数として普通にアドレス欄に 表示された情報でやり取りされます。基本的にCookieも使用しません。(認証キャッシュの為にのみ使用)
一見すると「こんなんで平気なんかい」っつー感じですが、リクエスト時には基本的に戻ってくるURLを指定するだけですので、 見られちゃっても全然問題なし。 レスポンス時の情報も sniff された場合、ユーザー名とニックネームはバレちゃいますが、 メールアドレスはSHAでハッシュされているので、特定不可能。 又、パスワード情報は一切やり取りしないので、やはり解析不可能。 レスポンス時にクライアント側ではHTTP_REFERER等でサーバーからのアクセスかどうかみたいな事は一切見ていないので、クライアントのURLにそれっぽい引数付けてアクセスしたら行けちゃいそうですが、そこは sig をチェックすることによって、 本当にサーバー側で認証されたURL引数なのかを検証出来る為、不正なアクセスは排除可能。 レスポンスURL自体を sig も含め引数ごと sniff してそのURLを別のユーザーが使用したら認証を不正に突破されちゃうのでは? と言う感じですが、これも、URL引数にサーバー側のタイムスタンプを含める事でURL自体の有効期間をクライアント側で判断可能。 つまり、再利用しようとしても「有効期限切れ」と言うことで却下できる。 タイムスタンプ自体もURL引数の一部として sig 生成用データに利用されているのでタイムスタンプ自体を詐称することも不可能。
と、言うことで考えられる脆弱性としては、
認証の通信自体をリアルタイムで監視、sniff し、レスポンスのURLを確認後、即効でそのURLにアクセスされた場合
位です。 この場合も、CookieやIPアドレス情報等を利用して、 既にログインしているユーザーと同一ユーザー名(name)のアクセスが他のロケーションからあった場合は 拒否する、と言うようなロジックをクライアント側に入れれば解決できると思います。 もしくは、信用して認証キャッシュしたURLリストを有効期限ぎれまで保持しておいて、 1回しか同一URLでは信用しないっつーのでもいいかもしれないです。
と言う事で、こんなんで平気なんです。素晴らしい。
このメソ知恵は訳に立ちましたか?