QiitaにXSS脆弱性

# **Qiitaに発生していた脆弱性について**

**※ エイプリルフールネタっぽいけど実際に発生していました。**
**※ 現在この脆弱性は修正済みです。**

## 問題のあった記事

> # **問題のMarkdown**
> 
> **[おいしいクッキーを食べたい人はここをクリック！] (data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+)**
> 
> ```txt
> **[おいしいクッキーを食べたい人はここをクリック！](data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+)**
> ```
> 
> ![ss (2014-04-01 at 07.47.31).jpg](https://qiita-image-store.s3.amazonaws.com/0/25060/cc0b498a-5a42-0aae-f4cd-ac81867576d5.jpeg)
> 
> # **ブラウザ別の挙動**
> 
> ## Chrome 33.0
> 
> データURIスキームの先で `document.cookie` を参照することは出来なかった。
> 
> ## Firefox 28.0
> 
> データURIスキームの先で `document.cookie` を参照することが **出来た** 。
> 
> ## Internet Explorer とかその他もろもろ
> 
> <del>編集リクエストに任せるぜ！</del>
> 
> # **考察**
> 
> ## 結局これってやばいの？
> 
> もし、 **`_qiita_login_session`** に **HttpOnly** 属性が付与されていなければ重大な脆弱性であったが、現状は心配いらないはず…（？）
> 
> ## っていうかMarkdown自体がJavaScript認めてる…？
> 
> 試しにこういうのも試してみる。
> 
> **[おいしいクッキーを食べたい人はここをクリック！](JavaScript:alert(document.cookie))**
> 
> ```txt
**[おいしいクッキーを食べたい人はここをクリック！](JavaScript:alert(document.cookie))**
> ```
> 
> なんだ！普通にChromeでも動くじゃないか！
> 
> # **結論**
> 
> Markdownを使うにせよユーザーにHTMLを自由に書かせるにせよ、 <ins>セッション用のクッキーはHttpOnlyにしておくことが最も重要</ins>ということを再確認しただけの記事でした。めでたしめでたし。

という記事を書いてたんですが、やはり脆弱性の扱いになるそうです。

**[ニュース - 「XSS脆弱性は危険，Cookieを盗まれるだけでは済まない」専門家が注意喚起：ITpro](http://itpro.nikkeibp.co.jp/article/NEWS/20061113/253479/)**

- 「XSS脆弱性が存在するサイト上に、<ins>偽のログイン画面や個人情報入力画面を作られることのほうが深刻だ</ins>」（徳丸氏）
- 「盗んだCookieをもとに個人情報などを収集することは“手間”がかかり、それほど容易ではないと考えられる。サイトを偽装されると個人情報を直接盗まれる恐れがあるので、こちらのほうがより深刻だ。加えてXSS脆弱性を悪用した偽装では、偽の入力フォームなどは本物のサイトの一部として表示されるので、URLやデジタル証明書（SSL証明書）を確認しても、偽物であることは分からない」（徳丸氏）
- 「XSS脆弱性が悪用されれば、ログイン画面やCookieを用意していない一般企業のホームページでも、偽の個人情報入力フォームを作られる恐れがある。どのようなサイトであっても、XSS脆弱性の被害は深刻になりうる。XSS脆弱性の危険性を再認識して、適切に対応する必要がある」（徳丸氏）

なるほど…言われてみると本当にその通りですね…また、コメント欄で説得力のある意見を頂いたのでこちらにも書いておきます。

- 「<ins>HttpOnlyはJavaScriptから直で読むことができなくするだけであって、JavaScriptをトリガとするHTTPリクエストでは普通にCookieが送られます</ins>」（@ngyukiさん）

## 事後処理

Qiitaの中の人(@yuku_tさん)から公開直後に直接ご連絡を頂き、記事を一時的に非公開にして、これが修正された今再び公開することになりました。対処に至った理由については以下のようであるということです。

```text
JavaScriptとData Schemeの使用は不可としておりましたが、意図せず許可状態になっておりました。直ちに問題が生じるかどうか、というよりは、この「こちらの認識と実際の動作が異なっていた」ことを重くみて今回のように対処させていただきました。
```

もし **`_qiita_login_session`** が **HttpOnly** じゃなかったら最初から内密に届出していたところなのですが、そうじゃなかったとしても問題のある記事でした。運営の皆様、ご迷惑をおかけしましたことをお詫びします。

# **XSSを部分的に認可する場合におけるセキュリティ対策**

<ins>JavaScriptが自由に使用可能</ins>なブログサービスについて言及していて…

> そうだとすれば、こういうサービスとかヤバいんじゃないでしょうか。
> 
> ![ss (2014-04-01 at 08.59.55).png](https://qiita-image-store.s3.amazonaws.com/0/25060/292dd27f-1e20-7ba7-8e47-4e49b250bdcd.png)
> 
> FC2ブログに限らず、<ins>JavaScriptが自由に使用可能</ins>なブログサービス全般ですね。 
> 
> ```text
> この記事を閲覧するにはログインが必要です。
> 以下の入力フォームよりログインしてください。
> ```
> 
> といったメッセージを
> 
> - いつも利用しているURL
> - いつも利用している雰囲気のページデザイン
> 
> こういった状況で出されたら信じてしまう人も多いのではないでしょうか。変なアドレスに飛ばされるフィッシングよりも遥かに識別するのが難しくなると思います。

訂正ばかりで申し訳ないのですが、上のような内容に対する意見をコメント欄で頂いたので、ここにどうすべきかをまとめておこうと思います。

- セッション処理に使われる目的などの **「重要なCookie」** は、 **「ユーザーが自由に編集可能なページ」** とは<ins>別のドメイン</ins>（もしくは<ins>別のパス</ins>）にする必要がある。
- **HttpOnly** は気休め程度ではあるがつけておいた方が無難ではある。

**「ユーザーが自由に編集可能なページ」** に **「重要なCookie」** を用いたコンテンツを記載したい場合、以下のどちらかの方法を採用する必要があります。当然、ドメインを別のものに分けているので、そのままコンテンツをそこに書くことは出来なくなっています。

## **`IFRAME`** 要素として埋め込む

はてなブログはこちらの方式を採用しています。言われないとフレームとはなかなか気づかないぐらい自然な実装になっていますね。

![ss (2014-04-04 at 10.12.18).jpg](https://qiita-image-store.s3.amazonaws.com/0/25060/35b71009-ce65-1926-bc0c-9f68c9e8348b.jpeg)

`IFRAME` 要素として表示しているページに対しては **クロスドメイン制約** がかかり、 **「Cookie」** や **「埋め込まれたCSRF対策トークン」** などが<ins>親ページのJavaScriptから取得できない</ins>ようにされているのがポイントです。@ngyukiさんからコメントを頂くまで私自身この特性については把握しておらず、勉強になりました。

## クッションページを設ける

FC2ブログはこちらの方式を採用しています。個人的にははてなブログの方が実装としては美しいと思いますが、こちらはJavaScriptを使わずともPHPだけで気軽に実装できるので、PHPしか扱えないような初心者であっても簡単にCSRF対策が出来る手段としては優秀だと思います。

![ss (2014-04-04 at 10.48.45).png](https://qiita-image-store.s3.amazonaws.com/0/25060/7a9d6c55-0bac-97a5-9954-ed92ae6f93ae.png)