Hashnodeにセッションハイジャックの脆弱性を報告した
2022年10月にHashnode(英語圏では人気のある技術ブログ作成サービス)に脆弱性を報告したのですが、最近になって修正されたようなので記事にしておきます。
Hashnode社の方には脆弱性について記事にすることの許可をもらっています[1]。
Hashnodeのカスタムドメイン設定機能について
Hashnodeの目玉機能として、ユーザーごとにブログを作成し、そのブログにカスタムドメインを紐づけられる機能があります。カスタムドメインのブログであっても、LikeやフォローといったHashnodeの認証が絡む機能を使うことができます。
カスタムドメインが設定されたブログでもフォローなどの機能が使える
hashnode.com
にログインしていれば、ユーザーのブログ(example.com
)を開いたときにもログイン状態が保持されているというわけです。
クロスドメインでログイン状態を保持するのはめちゃくちゃ難しい
以前別の記事でも書いたのですが、クロスドメインでログイン状態を安全に保持するというのはサードパーティーCookieなしでは非常に難しくなります。
Hashnodeに存在していたセッションハイジャックの脆弱性
Hashnodeがログイン状態をどうやって保持しているのか気になって調べると、カスタムドメインごとに認証用Cookieが発行されていることが分かりました。つまり、example.com
というHashnodeのブログにアクセスすると、(hashnode.com
への認証用Cookieとは別に)example.com
への認証用Cookieが付与されるというわけです。
このCookieの属性を調べてみると、Cookieがサブドメインに対しても送られる設定になっていることが分かりました。つまり、攻撃者がサブドメインのサイトをホスティングすれば、example.com
への認証用Cookieの値を収集できることになります。
さらに、hashnode.com
とカスタムドメインのブログごとの認証用Cookieが同一の値になっていたため、そのCookieを使ってHashnode本体のデータの取得や更新も可能であることが分かりました。
PoC
具体的には以下の手順で第三者のHashnodeアカウントを乗っ取ることができました。
- Hashnodeでブログを作り、所有するドメイン
example.com
を紐づける -
evil.example.com
というサブドメインのサイトを作り、セルフホスティングする -
example.com
のブログ記事の中などでhttps://evil.example.com
へのリンクを貼って踏ませる(例: 「未経験から1年で年収5000万になった話はこちら」というリンク) -
evil.example.com
のサーバーでHTTP Requestの内容を見ると、Hashnodeの認証用Cookieが含まれている - Hashnodeを開き、ブラウザのCookie設定に(4)を貼り付けると、第三者のアカウントでログイン状態になる
何が問題だったか
CookieのDomain属性
Cookieのdomain属性の値がexample.com
ではなく.example.com
となっている場合、そのCookieはサブドメインのホストにも送られてしまいます。
Set-Cookieにおいてdomain属性を空にすることで、同一のホストに対してのみCookieが送られるようになります。
Cookieの有効期限
Cookieがexample.com
にのみ送られるとしても、攻撃者がDNSレコードを書き換えれば任意のサイトにリクエストを流すことが可能になってしまいます。
この攻撃が可能な期間ができるだけ短くなるようにCookieの有効期限を短くするのが良さそうです(当時のHashnodeのCookieの有効期限は1年以上になっていた)。
認証用Cookieの値をドメインごとにユニークに
万が一ユーザーの認証用Cookieを攻撃者に奪われた場合にセッションハイジャックの被害が最小限になるように、Cookieの値はドメインごとにユニークにするべきです。少なくともhashnode.com
とユーザーごとのブログのドメインとの間でCookieの値は変えるべきだと思います。
また、ユーザーのカスタムドメインへの認証Cookieにより可能な操作は、Likeやフォローなど必要最低限に絞るのが良さそうです。
重要な操作の前には再認証を行う
当時のHashnodeでは窃取したCookieでアカウントのメールアドレスの変更や退会といった重要な操作も可能になっていました。セッションハイジャックやXSSの被害を緩和するために、これらの重要な操作の前には再認証を求めるのが良さそうです。
自戒
自分もサービスを運営していく中で可能なかぎり注意を払っていますが、それでも脆弱性を含めてしまうことがあります。脆弱性のないアプリケーションを作るのが一番ですが、規模が大きくなればミスや想定しきれないケースは生まれてしまうものだと思います。
開発者としては常に注意を払い、万が一脆弱性が見つかったときには真摯に対応したいと改めて思いました。
-
最近になって返信が来なくなったので記事の内容確認などはしてもらっていません ↩︎
Discussion