WebブラウザとWebアプリケーションのセキュリティについて考えてみたメモ

# はじめに
WebブラウザとWebアプリケーションのセキュリティについてまとめてみました。インフラ(サーバ、ネットワークなど)のセキュリティ対策は省きます。

# 参考
[体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践](https://www.amazon.co.jp/%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6-%E5%AE%89%E5%85%A8%E3%81%AAWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E7%AC%AC2%E7%89%88-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%8C%E7%94%9F%E3%81%BE%E3%82%8C%E3%82%8B%E5%8E%9F%E7%90%86%E3%81%A8%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E5%BE%B3%E4%B8%B8/dp/4797393165/ref=sr_1_1?s=books&ie=UTF8&qid=1542772815&sr=1-1&keywords=%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3+%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3
)

# 脆弱性とは
脆弱性とは悪用できるバグである

# Webアプリケーションへの攻撃
Webアプリケーションに対しての攻撃は2種類あります

## 能動的攻撃
* SQLインジェクションなど攻撃者が**直接Webサーバを攻撃**

→ 能動的攻撃を防ぐには**Webアプリケーションでセキュリティ対策が必要**

## 受動的攻撃
* 怪しいサイト閲覧 → マルウェア感染
  - Webブラウザ(AdobeFlashPlayerなどプラグイン含めて)に脆弱性があれば感染してしまう恐れ。
  - Webブラウザのセキュリティ対策が万全(下記)であれば怪しいエロサイトを見ただけではマルウェアに感染ということは起こりえないようです。しかし、逆にセキュリティアップデートされていないようなWebブラウザで怪しいサイトを見るとマルウェア感染も起こりえるようです。気をつけましょう。

* 正規サイトを悪用
  - 正規サイトに仕掛け → 仕掛けを閲覧 →　マルウェア感染、不正操作

* サイトをまたがった攻撃
  - 罠サイト→正規サイト(仕掛け済み)→ 仕掛け閲覧→不正操作

→　受動的攻撃を防ぐには**WebブラウザとWebアプリケーションでセキュリティ対策が必要**

**Webアプリケーションへの攻撃を防ぐにはWebブラウザとWebアプリケーションでセキュリティ対策が必要**
Webアプリケーションへの攻撃を防ぐにはWebブラウザがセキュリティに問題がないことが前提となる

# Webブラウザのセキュリティ
受動的攻撃に対して、Webブラウザでセキュリティ対策が必要だと述べました。ここではWebブラウザに**もともと備わるセキュリティ機能**についてまとめてみます。

## サンドボックス
JavaScriptやJavaアプレット、AdobeFlashPlayerなどで採用されている考え方。プログラム実行に制約がある。

制約

* ローカルファイルへのアクセス禁止
* プリンタなどの資源の利用禁止
* ネットワークアクセスの制限(同一オリジンポリシー)

## 同一オリジンポリシー
* JavaScriptなどのクライアントスクリプトからサイトをまたがったアクセスを禁止するセキュリティ上の制限
* 同一オリジンである条件
  - FQDNが一致
  - プロコトルが一致
  - ポートが一致

**ただし、それだと少し不便なので相手側の許可があれば同一オリジンでなくても通信できるCORSという規格が策定**

### Webブラウザセキュリティまとめ
* サンドボックス、同一オリジンポリシーなどもともと備わっているセキュリティ機能がある
* **Webブラウザに脆弱性があるとは、WEBブラウザが最新でなく(脆弱性のあるバージョンを利用)、脆弱性のあるプラグインを使用していたりなど**

* Webアプリケーションへの攻撃を防ぐにはWebブラウザがセキュリティに問題がないことが前提となる。よって、常に最新のバージョン(脆弱性のないバージョン)を利用する必要がある。

# Webアプリケーション側でのセキュリティ対策について
考慮しなくてはいけないWebアプリケーションの脆弱性の数はWebアプリケーションの機能によって増減します。例えば自分のプロフィールだけのWebアプリケーションであればセッションの脆弱性は発生しようがありません。よってここでは一般的なWebアプリケーションの脆弱性を列挙します。ここで一般的とは[Railsチュートリアル](https://railstutorial.jp/)で作成するtwitterライクなWEBアプリケーションを想定しています。 

## Webアプリケーションへの種類
参考書籍から

* XSS
* SQLインジェクション
* CSRF
* クリックジャッキング
* セッションハイジャック
  - 推測可能なセッションID
  - URL埋め込みのセッションID
  - セッションIDの固定化
* オープンリダイレクト
* HTTPヘッダインジェクション
* クッキー
  - クッキーの不適切な利用
  - クッキーのセキュア属性不備
* メール送信の問題
  - メールヘッダインジェクション
* ファイルアクセス
  - ディレクトリトラバーサル
* OSコマンドインジェクション
* ファイルアップロードにまつわる問題
* ファイルインクルード攻撃

https://www.ipa.go.jp/security/vuln/websecurity.html

上記がIPAに届出件数の多かった脆弱性や攻撃による影響度が大きいWebアプリケーションへの攻撃の一覧。
たくさんありますが、**逆にいうと一般的なWebアプリケーションに対しては以上の脆弱性を考慮すればWebアプリケーション側の対策としてはよいことになります**

# Webアプリケーションへの攻撃の対策まとめ
* Webブラウザ
  - もともと備わっているセキュリティ対策がある
  - 最新のバージョンを利用する。脆弱性のあるプラグインは使用しない
* Webアプリケーション
  - 上記にまとめたWebアプリケーションへの攻撃への対策を実施する


# 各脆弱性まとめ
## 補足
### Iframe
攻撃説明でIframeがでてくるので説明

* IframeとはHTMLの中に別サイトの文書を埋込できる技術のこと(クロスドメインアクセス)
*  JavaScriptはクロスドメインアクセスはできないがIframeでは異なるサイト(ドメインを超えて)を表示できる

## XSS クロスサイトスクリプティング
外部からの入力などに応じて表示が変化する箇所があり、この部分の**HTML生成の実装**に問題があるとXSSという脆弱性が生じる。

* 前提
  - 攻撃対象Webサービスにログイン済み
  - 罠サイトへ誘導される
  - 攻撃対象WebサービスにXSS脆弱性がある
* XSS脆弱性内容
  - 例えば、Webサービス側で検索実行ができる場合に検索文字列にJavascriptを仕込んで検索を実行。検索結果表示画面でエスケープされずにJavascriptが実行することができる。この場合、Javascriptのドメインは検索サービス提供側のドメインになる。
  - またはWebサービス側で入力によって動的にHTMLの属性値を生成できる処理がある場合にも属性値にJavascriptを仕込んで実行することができる
  - 偽サイトへ誘導 → 偽サイトのIframe内で攻撃対象サービスの検索実行(盗み出すJavascriptをリクエストに仕込む) → 検索結果にてJavascriptを自動実行してクッキー値をよみだし(同一ドメインなので可能)　→　ここまでくると表示することが可能なので、表示はせずに自分にメールとか、偽サーバへのログへの表示などでクッキーのセッション情報など盗みだし→  セッション情報を使ってなりすまし


### 対策
* 主要因は**<と”に対するエスケープ漏れ**。htmlの要素と属性値に特殊文字と解釈されないエスケープを実施する

* href属性やsrc属性の動的生成対応への対策
  * 入力値によって動的に href属性やsrc属性を生成しない
  * javascriptスキーマを入れれないようにする。http httpsのみのURLだけ。
  * javascriptだけでなく外部URLを挿入される場合も。その時はリンク先ドメイン名チェック。





## SQLインジェクション
SQL発行での不備がある場合に意図しないSQL実行することができる

### 原因
入力された文字列をそのまま使用してSQL実行してしまうなど

### 対策
* プレースホルダを使いましょう
* DBの権限は最小に


## CSRF クロスサイトリクエストフォージェリ
https://qiita.com/wanko5296/items/142b5b82485b0196a2da
https://html-coding.co.jp/knowhow/security/csrf/

* 罠サイトを閲覧しただけ(またはクリックなど)で、利用者のブラウザから勝手に**重要な処理を実行**させられる(重要な処理とはwebサービス側で用意されている処理。購入処理などwebサービスによって異なる)
* 前提
  - 攻撃対象Webサービスにログイン済み
  - 偽サイトへ誘導される
  - 攻撃対象WebサービスにCSRF脆弱性がある
* CSRF脆弱性内容
  - 偽サイトへ誘導 → 偽サイト閲覧すると(またはリンククリックなど)iframeで処理が攻撃対象Webアプリケーションにリクエスト(**クッキー自動送付**)、攻撃対象Webアプリケーションは正規ユーザの通常処理と思い処理を実行する(ここで意図しない処理が実行される可能性。例えば送り先を変更＆商品購入)
  - 攻撃リクエストを送るリンクなどは表向きは普通の画面になっているが、押すと上記処理が走る感じで巧妙になっている


### 原因
* from要素のaction属性にはどのドメインのURLでも指定できる
* クッキにー保管されたセッションIDは対象サイトに**自動的に送信**される

### CSRFとXSS
* CSRFはリクエストに対するサーバ側の処理を悪用するので悪用内容はサーバ側に用意された処理に限定
* XSSはWebブラウザ上でクッキーを使った悪用はなんでもできる。攻撃はXSSのほうが広い

### 対策
* 正規利用者の意図したリクエストの確認をする必要がある
  - 意図したリクエスト
     * アプリケーションの画面上で正規利用者が自ら実行ボタンを押したかどうか。
  - 意図しないリクエスト
     * 罠サイトからのリクエスト
* 対策
  - referefチェック
  - パスワード再入力
  - トークンの埋込(主なフレームワークではトークンを埋め込んで正規リクエストか判定してくれる)

## クリックジャッキング
iframe要素とCSSで透明にした攻撃対象ページと罠サイトを重ね合わせ、利用者がきづかないうちに攻撃対象サイトでのクリックを誘導する

### 対策
* 重要な処理のの一つ手前の入力フォームにはX-Frame-Optionsを設定する(Deny または SAMEORIGIN)
* X-Frame-Options
  - frame及びiframeでの参照を制限する。主要ブラウザで採用されている。Webアプリケーション側でレスポンスヘッダにX-Frame-Optionsを設定することで制限が有効になる
* 問題なければ全ページでX-Frame-Optionsを設定する

## セッションハイジャック
なんらかの原因で利用者のセッションIDが第三者に知られてセッションIDを悪用してなりすましされること。以下第三者がセッションIDを知るための手段

### セッションIDの推測
セッション管理機構を自作すると推測されやすいのでWebアプリケーションフレームワークが備えるセッション機構を利用する
    
### セッションIDの盗み出し
* URLにセッションIDを埋め込まない
* XSS脆弱性に対応する
* クッキーのセキュア属性を設定する

### セッションIDの強制(セッションIDの固定化)
* ログイン時にセッションIDを変更する

## オープンリダイレクト
利用者が知らないうちに別ドメインに遷移してフィッシング詐欺に悪用されること。利用者が信頼しているドメイン上にオープンリダイレクト脆弱性があると、利用者は自分が信頼するサイトを閲覧しているつもりで知らない間に罠サイトに誘導され重要情報を入力してしまうこと


### 原因
* リダイレクト先のURLをがいぶから指定できる かつ リダイレクト先のドメイン名のチェックがない
* 外部のドメインに遷移することが仕様だったり、外部ドメインに遷移することが自明であれば脆弱性ではない

### 対策
* リダイレクト先のURLを固定
* リダイレクト先のURLを直接指定せずに番号指定
* リダイレクト先のドメイン名をチェック

## HTTPヘッダインジェクション
レスポンスヘッダを出力する際のパラメータ中に改行を挿入することで被害者のブラウザ上で、任意のレスポンスヘッダの追加、レスポンスボディの偽造ができてしまう脆弱性

### 対策
外部からのパラメータをHTTPレスポンスヘッダとして出力しないこと

## クッキー出力にまつわる脆弱性

* クッキーを利用すべきでない目的でクッキーを使っている
    - 例えば、セッションID(トークン)の保管場所として利用すべきであり、データそのものをクッキーには保存しない。**逆にいうとセッションIDに保管場所としてよい**。Railsでもデフォルトはクッキー
 
* クッキーの出力方法に問題がある
  - セキュア属性の不備
    - セキュア属性を設定することでHTTPS環境でしたクッキーを送信しないようにする

### 対策
* クッキーに変更されては困るデータを保存しない
* セキュア属性つける

## メールヘッダインジェクション
宛先や件名などのメールヘッダを外部から指定する際に改行文字を使ってメールヘッダや本文を追加、変更して件名、本文を改変されたり、迷惑メールの送信に悪用、ウイルスメールの送信に悪用される脆弱性

### 対策
* メール送信には専用のライブラリを使用する。直接sendmailコマンドで送信したりしない
* 外部パラメータをメールヘッダに直接使わない


## ディレクトリトラバーサル
外部からパラメータの形でサーバ上のファイル名をしてしてファイルの閲覧、改ざん、削除ができる脆弱性

### 対策
* 外部からファイル名を指定できないようにする
  - これさえあれば下記２つはいらずに根本対応できる
* ファイル名にディレクトリ名(../)が含まれないようにする
  - 想定したディレクトリにのみアクセスさせるため
* ファイル名を英数字限定
  - 攻撃で使用する記号文字を使えないようにするため



## OSコマンドインジェクション
Webアプリケーションでシェル経由でoSコマンドを呼び出す場合に呼び出し方に問題があると意図しないOSコマンドが実行可能になり,ファイル改ざん、削除、別サーバへの攻撃など悪用される脆弱性

### 対策
* OSコマンドをよびださない(シェルを呼び出せる機能を利用しない)
* 呼び出してもOSコマンドに外部パラメータを直接指定しない


## ファイルアップロードにまつわる問題
* アップロード機能に対するDOS攻撃
* アップロードしたファイルをスクリプトとしてWebサーバ上で実行
* 仕掛けを含むファイルを利用者にダウンロード攻撃
  - Content-Typeを誤認させることでXSS
  - 利用者がPDFとしてダウンロード → HTMLと解釈させる,Javascript実行(XSS)

### 対策
* 容量チェック
* ファイルを公開ディレクトリに保存しない。拡張子を指定できないようにする
* ダウンロード
  - ファイルダウンロード時にcontent-Typeを正しく設定する
  - レスポンスヘッダX-Content-Type-Options: nosniffを指定する



## ファイルインクルード
includeなどに指定するファイル名を外部から指定できる場合に意図しないファイルを指定でき脆弱性になる

### 対策
外部からファイル名を指定できないようにする

## PDFにまつわる脆弱性
割愛

## 今回の一般的なWEbアプリケーションに含まれない機能の脆弱性
概要だけさらっと

### 構造化データの読み込みにまつわる問題
### evalインジェクション
スクリプトを解釈して実行できるevalのおうな機能を利用しているページ

#### 対策
evalに相当する機能を使わない
外部パラメータを引数として使わない

### 安全でないデシリアライゼーション
外部からの値をデシリアライズ処理している

#### 対策
シリアライズ、デシリアライズを使わない
外部からの値を使わない

### XML外部実体参照
XMLを外部から受け取り解析しているページ

#### 対策
XMLではなくjsonを使う

### 共有資源の脆弱性


#### 対策
* 共有資源を避ける
* 適切な排他制御

### キャッシュの脆弱性
割愛


### webapi実装の脆弱性
割愛




# RailsチュートリアルのWebアプリケーション脆弱性への対応
上記脆弱性に対するRailsチュートリアルの対応を述べます

###  XSS
ViewではデフォルトHTMLエスケープされる

### SQLインジェクション
プレースホルダによるSQL組み立て

### CSRF
Rails側でトークンの生成とチェック機能がある

### クリックジャッキング
RailsのレスポンスヘッダのX-Fram-optionsはデフォルトでSAMEORIGIN


### セッションハイジャック

- 推測可能なセッションID
  * Webアプリケーションフレームワークが備えるセッション機構を利用 
- URL埋め込みのセッションID
    * URLにセッションIDを埋め込んでいない
    * secure属性を設定
- セッションIDの固定化
    * ログインするたびに異なるセッションIDを付与

### オープンリダイレクト
リダイレクト先を外部から指定できない

### HTTPヘッダインジェクション
HTTPヘッダは自分で作らずRailsに任せる

### メールヘッダインジェクション
* 外部からのパラメータでメールヘッダ作成していない
* hiddenパラメータに宛先を保持していない

### クッキー
- クッキーの不適切な利用
  * セッションIDをクッキーに保持していて、データは保持していない
- クッキーのセキュア属性不備
  * secure属性を設定

### ファイルアクセス
- ディレクトリトラバーサル
  * 相対パス、絶対パスを指定できない

###  OSコマンドインジェクション
OSコマンドを直接たたくことが無い

### ファイルアップロード&ダウンロードにまつわる問題
* 拡張子チェックあり(画像ファイルのみ)
* 容量制限あり
* ランダムなファイル名に変更
* レスポンスヘッダでcontent-typeを強制
  - デフォルトで`X-Content-Type-Options:nosniff`を設定する。拡張子通りに表示
  - 他ユーザがアップロードしたファイルをブラウザでURLアクセス可能なのでそのときに画像として表示される(HTML表示などされXSS混入を防ぐ)

  
### ファイルインクルード攻撃
外部からファイルをインクルードしていない

## 追加であったほうが良い機能
* ログイン時に一定時間に何回アクセスで制限するといったアクセス制限は入れたほうがよいかもしれない
* 同様にファイルアップロードの回数制限など

# まとめ
## WebブラウザとWebアプリケーションのセキュリティ
* 主に受動的攻撃の、偽サイトなどを使用した攻撃が多い
* Webブラウザのセキュリティ対策していないと怪しいサイトを閲覧しただけでもマルウェア感染などありえる。が大体偽サイトを使用した受動攻撃が多い
* 基本的に外部からのパラメータをそのまま使用するのは控えるほうが良い
* 上記からわかるようにRailsのようなフレームワークを使うとセキュリティ対策がデフォルトで施されているのでセキュリティを意識せずにセキュリティ対策をすることができます。しかし今回Webアプリケーションのセキュリティについてまとめたことで一般的なWebアプリケーションについてどのような脆弱性の可能性があるのか、そしてその脆弱性に対してどのような対策をとればよいのか、またフレームワークの裏側でどのように対策しているのか知ることができました。
* 詳細は参考書籍を参照お願いします