読者です 読者をやめる 読者になる 読者になる

Disqus にいくつか DOM based XSS があった件

概略

サイトのコメント欄の外部委託系サービスの disqus.comにいくつか DOM based XSS がありまして修正されました.location.hash 部分の url encode が行われない IE, Chrome, Opera で問題があったことは確認しています.

まず一つ目は,コメント欄の埋め込みスクリプトにありました.

脆弱性とその修正を確認しているのは,blogid.disqus.com/admin/universal/ にて表示されるコードを埋め込むタイプで,blogid.disqus.com/embed.js というスクリプトです.

こちらのコードは,埋め込んだドメイン上で動作していましたので,このタイプのコードを埋め込んでいたドメインで提供されているサービスに影響があった可能性があります.disqus.com ではuniversal code とは別に,特定の幾つかのブログサービス向けに専用の手順やコードを用意していますが,そちらで利用していた場合にも,影響があった可能性があります.

もう一つは,disqus.com 本体の,ログイン周りのコードです.disqus.com の幾つものページでログインしていない状態でのみ使われるコードに問題がありました.

2012/08/24 17時現在はどちらも対応済みです.

時系列

  1. 最初に気がついたのが,08/21 の 12時前

  2. 実際のコードと再現手順を確認するためにアカウントを新規で作ったあと,コードを検証してコンタクトフォームから通報して,定型の応答が来たのが  08/21 の 12:40 頃.

  3. その後しばらく,音沙汰が無いまま 45時間後の 08/23 の 9時過ぎに「担当チームに回したよ」とのメールが到着.

  4. メールに気がついた,11時半頃に一応の修正を確認.

  5. 前後して,disqus の embed の status が一時的に不調

  6. 色々確認して,13時半過ぎに直ったと Tweet.

  7. 19時過ぎにそれどっち側の話?とやりとり

  8. 08/24 14 時ごろに disqus.com 本体側のコードも修正.

  9. 08/24 17 時ごろにひとまず記事に

技術的な詳細

埋め込みコメント欄

disqus の埋め込みコメント欄は,埋め込まれる側の html に div#disqus_thread とスクリプトを追加してもらい,スクリプトでこの div の中にコメント欄を形成する形になってます.

コメント欄本体は disqus.com の iframe 上に作られてますが,うまく iframe が読み込めないなどに備えて,div の直下にいくつか要素が追加されます.

この追加されるコードで location.href をそのまま innerHTML に挿入している以下の様なコードがあり,div の下に iframe のコメント欄が形成される一瞬の隙をついて location.hash に載せたコードが実行可能な状態になってました.

q = f.setTimeout(function () {
 t.innerHTML += '<p>Loading DISQUS seems to be taking longer than usual, <a href="' + f.location.href + '">reload</a>?</p>'
 },1000)

記事執筆時点の実装では,onclick で location.reload() するように変更されました.

disqus.com 本体

disqus.com では,ログイン・ログアウト用のパーツの生成処理にテンプレートを使ってます.

このうちログイン用のパーツで,ログインしたあとの遷移先の指定が以下の様なテンプレートになっていました.

<li data-analytics="header login"><a rel="login" href="<%= data.urlMap.login %>?next=<%= document.location.href %>">Login</a></li>

このため,テンプレートが展開されてページの DOM に追加されるときに,location.hash に載せたコードが実行可能な状態になってました.

これが現在は,encodeURIComponent を使う形に修正されました.