XSSに関して今一度学ぼう


## はじめに
近年セキュリティに関してのニュースが絶えません。
技術の進化により出来る事が多くなっている事、フレームワークなどを使う事で前提知識がなくてもアプリケーションを作れるようになった事、そういう事が原因で後を絶たないのかと思います。

脆弱性コンテストとかも開催されており、かなりホットな業界ですねw
今日は有名どころの、「XSS」に関してまとめました。

## オリジンとは？
「スキーム」「ホスト」「ポート」の3つの組み合わせをオリジンという。
[RFC 6454 - The Web Origin Concept](http://tools.ietf.org/html/rfc6454)で制定

クロスオリジンの場合には原則としてリソースの読み書きが禁止になることを「同一オリジンポリシー」と言います。基本的にjsが制御できるのは同一オリジンのみです。

そりゃそうですよね。同一オリジン以外でできたら、別tabで開いてたGmailのデータ抜かれてたなんて事おきちゃいますからね。

その他同一オリジンにて制約されているものの例としては

```
XMLHttpRequest 
Canvas
Web Storage
```
 XMLHttpRequset Level 2 に対応しているブラウザであれば、XMLHttpRequest でクロスドメイン通信が可能になりました。

一方で同一オリジンポリシーとは別の制約を定めているのはcookieとかですかね。

## XSS

クロスサイト→クロスオリジンと理解してもらえれば

### 攻撃者の目的
- 不正なプログラムを拡散させる
- cookieなどの個人情報を取る

### reflected型

外部から受け取ったパラメータをWebページに表示する際に起こる脆弱

よくある例としては、検索ページや、問い合わせフォームの確認画面、マイページなど。
IEなどではXSSフィルターなどを搭載しているケースもあるし、ChromeやSafariも防止対策が行われている。とはいえFirefoxでは対策されていなかったり、100%防ぐ事はできないので、理解しておきましょう。

※xssフィルタとは
・送られてくるデータが、レスポンスにそのまま含まれている
・script実行につながる可能性があると判断される
上記の条件に該当する場合のみスクリプトを無効にする

```example
http://hoge.com/?name="fuga"
```
↓

```result
fugaさん、こんにちは！
```

```attack_example
http://hoge.com/?name="fuga"><script>alert("脆弱性発見！")</script>
```

スクリプトが読み込まれてアラートが実行されれば任意のスクリプトを実行できる。
これの問題点は、他人を誘導してこのURLからアクセスさせる→cookie情報GETなんてことができるから怖い。

### stored型

スクリプトが持続的に埋め込まれ、効果が永続するタイプの脆弱

これは昔2chでもありましたね。

参考)
[予告.inが不正コード被害、閲覧で２ちゃんねるに犯行予告投稿](http://internet.watch.impress.co.jp/cda/news/2008/08/04/20469.html)

ユーザ投稿型のコンテンツをもっているサイトなどで、コンテンツにスクリプトが埋め込まれ表示される度に実行されるパターンが多いですね。



### DOM型

動的にコンテンツを操作するようなスクリプトが組まれているアプリケーション上で発生する脆弱
XMLHttpRequestを使って動的にコンテンツを操作するようにかかれている正規のスクリプトのURLを変更することで、悪質なコンテンツを差し込む事ができる。


![スクリーンショット 2014-12-18 11.36.19.png](https://qiita-image-store.s3.amazonaws.com/0/5365/49f91cc9-f89f-eb52-212a-a148d362016e.png "スクリーンショット 2014-12-18 11.36.19.png")

ちなみにIPAの[IPAテクニカルウォッチ「DOM Based XSS」に関するレポート～JavaScriptでHTMLを操作するアプリは要注意！～](http://www.ipa.go.jp/files/000024729.pdf)の画像を引用すると、
問題コードは大体独自開発によるものです。

- 開発者が知識をつける
- ライブラリに頼る場合は定期的なアップデートは忘れずに！

下記のようなものを使っている場合は要注意です。

```
location.href
location.search
location.hash
document.cookie
document.referrer
window.name
```
従来は同オリジンでしか通信できなかったが、現在のブラウザではXHR Level2実装により同オリジン以外でも通信できるようになった。

```
var url = location.href.substring( 1 );
var xhr = new XMLHttpRequest();
xhr.open( "GET", url, true );
xhr.onreadystatechange = function(){
    if( xhr.readyState == 4 && xhr.status == 200 ){
        div.innerHTML = xhr.responseText; // 取得したコンテンツを表示
    }
};
xhr.send();
```

例えば、
https://www.hoge.co.jp/#//hack.com/vi/hack_content
などに誘導アクセスさせると```hack.com/vi/hack_content```とアクセスをして
htmlにresponseを代入してしまいます。
非常に問題ですね。

```対策
var xhr = new XMLHttpRequest();
xhr.open( "GET", "/get_content", true );
xhr.onreadystatechange = function(){
    if( xhr.readyState == 4 && xhr.status == 200 ){
        div.innerHTML = xhr.responseText; // 取得したコンテンツを表示
    }
};
xhr.send();
```

当たり前ですが、urlは固定が望ましいです。
固定しないのであれば、hashでlistを作って対応するなどしてもらえれば問題ないです。

加えてIEは更にクソ仕様があります。

レスポンスヘッダーに```X-Content-Type-Options: nosniff```を付与しないと```Content-Typeをapplication/json```で指定していても```http://hoge.com/api.json/a.html```ってやるとhtmlとして開いてしまいます。

参考)
[X-Content-Type-Options: nosniff つかわないやつは死ねばいいのに!](http://d.hatena.ne.jp/hasegawayosuke/20110106/p1)

[検証ツール](http://blog.ohgaki.net/dom-xss-1)もあるみたいなので、試してみてもいいかもしれません。

## 結論

結局開発者がセキュリティに関して理解しておくことが最重要です。

もう少し具体的な手段でいくと "入力の制御" & "出力の制御"をちゃんと行うという一言に尽きるのではないでしょうか。
XSSであればサニタイジングが必要です。
サニタイジングをどうやればいいんだよって人は[ココ](http://viral-community.com/blog/html-sanitizing-escape-1859/)に詳しく載ってます。