🍪

Hashnodeにセッションハイジャックの脆弱性を報告した

2024/02/22に公開

2022年10月にHashnode(英語圏では人気のある技術ブログ作成サービス)に脆弱性を報告したのですが、最近になって修正されたようなので記事にしておきます。

Hashnode社の方には脆弱性について記事にすることの許可をもらっています[1]

Hashnodeのカスタムドメイン設定機能について

Hashnodeの目玉機能として、ユーザーごとにブログを作成し、そのブログにカスタムドメインを紐づけられる機能があります。カスタムドメインのブログであっても、LikeやフォローといったHashnodeの認証が絡む機能を使うことができます。

Hashnodeのブログごとのログイン機能カスタムドメインが設定されたブログでもフォローなどの機能が使える

hashnode.comにログインしていれば、ユーザーのブログ(example.com)を開いたときにもログイン状態が保持されているというわけです。

クロスドメインでログイン状態を保持するのはめちゃくちゃ難しい

以前別の記事でも書いたのですが、クロスドメインでログイン状態を安全に保持するというのはサードパーティーCookieなしでは非常に難しくなります。

https://zenn.dev/catnose99/articles/6c9851560c132e

Hashnodeに存在していたセッションハイジャックの脆弱性

Hashnodeがログイン状態をどうやって保持しているのか気になって調べると、カスタムドメインごとに認証用Cookieが発行されていることが分かりました。つまり、example.comというHashnodeのブログにアクセスすると、(hashnode.comへの認証用Cookieとは別に)example.comへの認証用Cookieが付与されるというわけです。

このCookieの属性を調べてみると、Cookieがサブドメインに対しても送られる設定になっていることが分かりました。つまり、攻撃者がサブドメインのサイトをホスティングすれば、example.comへの認証用Cookieの値を収集できることになります。

example.comへの認証目的で付与されたCookieをサブドメインのサイトで収集できる

さらに、hashnode.comとカスタムドメインのブログごとの認証用Cookieが同一の値になっていたため、そのCookieを使ってHashnode本体のデータの取得や更新も可能であることが分かりました。

PoC

具体的には以下の手順で第三者のHashnodeアカウントを乗っ取ることができました。

  1. Hashnodeでブログを作り、所有するドメインexample.comを紐づける
  2. evil.example.comというサブドメインのサイトを作り、セルフホスティングする
  3. example.comのブログ記事の中などでhttps://evil.example.comへのリンクを貼って踏ませる(例: 「未経験から1年で年収5000万になった話はこちら」というリンク)
  4. evil.example.comのサーバーでHTTP Requestの内容を見ると、Hashnodeの認証用Cookieが含まれている
  5. Hashnodeを開き、ブラウザのCookie設定に(4)を貼り付けると、第三者のアカウントでログイン状態になる

何が問題だったか

CookieのDomain属性

Cookieのdomain属性の値がexample.comではなく.example.comとなっている場合、そのCookieはサブドメインのホストにも送られてしまいます。

Set-Cookieにおいてdomain属性を空にすることで、同一のホストに対してのみCookieが送られるようになります。

https://blog.tokumaru.org/2011/10/cookiedomain.html

Cookieの有効期限

Cookieがexample.comにのみ送られるとしても、攻撃者がDNSレコードを書き換えれば任意のサイトにリクエストを流すことが可能になってしまいます。

この攻撃が可能な期間ができるだけ短くなるようにCookieの有効期限を短くするのが良さそうです(当時のHashnodeのCookieの有効期限は1年以上になっていた)。

認証用Cookieの値をドメインごとにユニークに

万が一ユーザーの認証用Cookieを攻撃者に奪われた場合にセッションハイジャックの被害が最小限になるように、Cookieの値はドメインごとにユニークにするべきです。少なくともhashnode.comとユーザーごとのブログのドメインとの間でCookieの値は変えるべきだと思います。

また、ユーザーのカスタムドメインへの認証Cookieにより可能な操作は、Likeやフォローなど必要最低限に絞るのが良さそうです。

重要な操作の前には再認証を行う

当時のHashnodeでは窃取したCookieでアカウントのメールアドレスの変更や退会といった重要な操作も可能になっていました。セッションハイジャックやXSSの被害を緩和するために、これらの重要な操作の前には再認証を求めるのが良さそうです。

自戒

自分もサービスを運営していく中で可能なかぎり注意を払っていますが、それでも脆弱性を含めてしまうことがあります。脆弱性のないアプリケーションを作るのが一番ですが、規模が大きくなればミスや想定しきれないケースは生まれてしまうものだと思います。

開発者としては常に注意を払い、万が一脆弱性が見つかったときには真摯に対応したいと改めて思いました。

脚注
  1. 最近になって返信が来なくなったので記事の内容確認などはしてもらっていません ↩︎

Discussion