nginx/Railsのセキュリティ対策メモ

nginx/Railsのセキュリティ対策で今まで行なってきたことのメモです。

# nginx

## Webサーバのバージョン情報をレスポンスに表示させない

### 理由
バージョン情報が漏洩することで、既知の脆弱性を狙った攻撃を受けるリスクが高まる
また今後新たな脆弱性が見つかった時に攻撃対象となる可能性がある

### 対応方法
Nginxのバージョン情報を表示させないようにするにはnginx.confのhttpディレクティブに```server_tokens off;```を追加します。

```nginx.conf
http {
    server_tokens off;
    ...
```
参考：[Nginx導入時やること](http://qiita.com/kidach1/items/985efebba639713c562e)

ちなみにnginxを使っていること自体を隠す場合には拡張モジュールが必要となるようです。
[[Nginx] レスポンスヘッダを限りなく消す](http://yume-build.com/blog/archives/257)
[Nginxでレスポンスヘッダの一部を隠蔽する方法](http://qiita.com/noraworld/items/50781bcaa5bf28802cd0)

## レスポンスヘッダにX-XSS-Protectionを付与する
### 理由
クロスサイトスクリプティングの脆弱性により、罠ページにアクセスした利用者のブラウザ上で任意のスクリプトが実行される可能性がある。

### 対応方法
nginxのconfファイルにX-XSS-Protectionヘッダーを追加する。

```default.conf
add_header X-XSS-Protection "1; mode=block";
```

## レスポンスヘッダにContent-Security-Policyを付与する
### 理由
クロスサイトスクリプティングなどの脆弱性につながる可能性がある。

### 対応方法
nginxのconfファイルにContent-Security-Policyヘッダーを追加する。

```default.conf
add_header Content-Security-Policy "default-src 'self'";
```

## レスポンスヘッダにStrict-Transport-Securityを付与する
### 理由
リダイレクト攻撃など、なんらかの理由でHTTPS通信がHTTP通信に変更されてしまった場合、特にクライアント側で通信路の安全性が確認できなくなる。

### 対応方法
nginxのconfファイルにStrict-Transport-Securityヘッダーを追加する。

```default.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
```

## SSLの暗号方式を見直す
### 理由
強度の低い暗号方式をサポートすると、通信の盗聴や改ざんなどが行われる可能性がある。

### 対応方法
参考：[httpsだからというだけで安全？調べたら怖くなってきたSSLの話!？](http://qiita.com/kuni-nakaji/items/5118b23bf2ea44fed96e)

あくまで例ですが以下のような設定にしています。

```default.conf
server {
  ~
  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!EXPORT:!DES:!3DES:!MD5:!DSS:!ADH:!AECDH;
```
参考サイトの設定に加えて認証機能を提供していないCipher Suite（ADH-AES128-SHAなど）を除外するように修正しています(中間者攻撃を防ぐため)

## レスポンスヘッダにX-Download-Optionsを付与する
### 理由
X-Download-Optionsを指定していないとIEでファイル保存のダイアログに「開く」ボタンが表示される。
ブラウザ上で直接ファイルを開くことでURLに対応するドメイン上のリソースとしてブラウザ内で表示される可能性がある。
この機能を悪用してクロスサイトスクリプティングを実行することで、個人情報の漏えいの被害につながる危険性が存在する。

### 対応方法
nginxのconfファイルにX-Download-Optionsヘッダーを追加し値に"noopen"を指定する。

```default.conf
add_header X-Download-Options "noopen";
```

# Rails

## publicディレクトリに.svnを残したままにしない

###  理由
Subversionのentriesファイルからバージョン管理情報が漏えいし、攻撃のヒントを与える可能性がある。

###  対応内容
デプロイ時に.svnを削除するように自動化しておきます。

## リクエストパラメータでファイルパスを渡すAPIを作成しない

### 理由
パストラバーサルの脆弱性によりWebサーバの権限で任意のファイルの情報が取得できてしまう。
その結果、機密情報が漏えいする可能性がある。

### 対応内容
IDなどファイルパスに変わる情報をパラメータとして指定するようにします。

## HTTPSで通信されるSet-Cookieにsecure属性を付与する

### 理由
HTTPS通信で付与されたcookieの内容がHTTP通信で送信されると、cookieの内容が漏えいする可能性がある

### 対応方法
```config/initializers/session_store.rb``` の ```session_store```の部分でsecureオプションを付与します

```ruby:session_store.rb
Rails.application.config.session_store ..., secure: Rails.env.production?
```
参考：[Railsエンジニアが安心して新年を迎える方法](http://qiita.com/masarakki/items/e498d257a2105d055281)

## セッション情報をCookieではなくデータベースに持たせる
### 理由
Cookie情報が漏洩するとアカウント乗っ取りなどによる攻撃を受ける可能性が高くなる

### 対応方法
[activerecord-session_store](https://github.com/rails/activerecord-session_store)を使います。

参考：[Rails4でsession storeをActiveRecordに変更](http://easyramble.com/rails-active-record-session-store.html)

## HostヘッダやRefererのチェック処理を入れる
### 理由
HostヘッダやRefererを改ざんした場合、レスポンスのLocationヘッダに指定した文字列が出力される。
罠ページの閲覧やメール添付URLの閲覧などを行った際に、偽ページにリダイレクトされる可能性がある。
参考：[Host:リクエストヘッダによるXSS](http://d.hatena.ne.jp/hasegawayosuke/20151110/p1)

### 対応方法
Railsのbefore_actionでHostヘッダやRefererのドメインチェックを行ないます。
※これがベストな方法かはわからないです。


## cache-controlヘッダの設定を変更しキャッシュ保存を行なわないようにする
### 理由
デフォルトのprivate指定ではプロキシなどにレスポンスがキャッシュされる可能性がある。

### 対応方法
Railsのコントローラに以下を追加

```application_controller.rb
prepend_before_action :set_headers

def set_headers
  response.headers['Cache-Control'] = 'no-store'
  response.headers['Pragma'] = 'no-cache'
end
```
※nginxのconfファイルに追加する方法だとprivate指定の設定が残ってしまう。