Webアプリケーションのおすすめセキュリティ設定

## はじめに
Ruby + NginxでWebサイトを構築し、脆弱性診断で毎回ほぼ同じことを指摘されるので
この際まとめてみることにしました。
昨今のフレームワークはセキュリティ対策もある程度されており、余程ひどいコードを書かない限りは大丈夫だと思いますが、これから説明する設定を付け足すだけでより堅牢なサイトになり得るのでこの機会にみなさんのサイトにも適応されてはいかがでしょうか。（記事を書くにあたりApacheの設定も一緒に調べて記載していますので参考になればと思います。）

## バージョン情報
Nginx：1.12.1
Ruby：2.2.3〜2.4.1
Rails：4.2.4〜5.1.2

## X-Frame-Optionsヘッダ（XFO）
#### 説明
X-Frame-Options HTTPレスポンスヘッダは、ブラウザが `<frame> `や`<iframe>` や `<object>`を
ページ内部に表示することを許可するかを設定することができます。
#### 想定される脆弱性
**クリックジャッキング**
自身のサイトがいつの間にか罠サイトの中に `<iframe>` で埋め込まれてしまった結果、
罠サイトに来訪したユーザーによって意図しないうちに自分のサイトが操作されてしまうような脆弱性です。
#### 対策
HTTPレスポンスヘッダをX-Frame-Options: **DENY** または **SAMEORIGIN**とすることが望ましいです。
#### 対応方法
- Nginx

```nginx:nginx.conf
add_header X-Frame-Options DENY;
```

- Apache

```apacheconf:httpd.conf
Header append X-Frame-Options DENY
```

- Rails

```ruby:config/application.rb
module Projectname
  class Application < Rails::Application
    config.action_dispatch.default_headers["X-Frame-Options"] = "DENY"
  end
end
```


## HTTP Strict-Transport-Securityヘッダ（HSTS）
#### 説明
*HTTPS* 通信を強制するようブラウザに伝達するセキュリティ機能です。
#### 想定される脆弱性
Webサイトを閲覧しているユーザーがHTTPS対応ページにHTTPでアクセスしてしまう恐れがあります。
#### 対策
HTTPレスポンスヘッダに **Strict-Transport-Security** 設定を付与します。
*max-age* はブラウザがサイトにHTTPSで通信させる有効期限
*includeSubDomains* は、サブドメインに対してもHSTSを適用
#### 対応方法

- Nginx

```nginx:ngixn.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
```

- Apache

```apacheconf:httpd.conf
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
```

- Rails

```ruby:config/environments/production.rb
  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  config.force_ssl = true
```
※Rails5.1未満は設定方法が異なるようなので注意が必要です。（[参考サイト](https://qiita.com/jnchito/items/9ec312488c7f7ffbbe69)）

#### 注意点
*HTTP* と *HTTPS* が混在するサイトで*Strict-Transport-Security* を適応すると有効期限内はサイトにアクセス出来なくなる可能性があります。
*max-age* は5分、1週間、1ヶ月と徐々に期間を伸ばし、サイトに問題ないことが確認出来たら1-2年に設定するようです。（[参考サイト](https://hstspreload.org/#deployment-recommendations)）


## X-XSS-Protectionヘッダ
#### 説明
ブラウザのXSSフィルターを強制的に有効にすることが出来ます。
#### 想定される脆弱性
クロスサイトスクリプティング（XSS）の予防策
#### 対策
HTTPレスポンスヘッダに **X-XSS-Protection** 設定を付与します。
#### 対応方法
- Nginx

```nginx:ngixn.conf
add_header X-XSS-Protection "1; mode=block";
もしくは
add_header X-XSS-Protection "0";
```

- Apache

```apacheconf:httpd.conf
Header set X-XSS-Protection "1; mode=block" 
もしくは
Header set X-XSS-Protection "0" 
```

- Rails

デフォルトで設定されているためNginx + Railsの組み合わせで利用する場合はNginx側の設定は不要です。
双方で設定した場合はChrome開発者ツールで下記のようなエラーが発生します。

```
Error parsing header X-XSS-Protection: 1; mode=block, 1; mode=block: expected semicolon at character position 14. The default protections will be applied.
```


## X-Content-Type-Optionsヘッダ
#### 説明
ブラウザが *Content-type* を検査（sniffing）することを無効にします。
#### 想定される脆弱性
IEや一部ブラウザにおいて *Content-Type* に従わない動作をした場合に、クロスサイト・スクリプティング(XSS)が発生する可能性があります。
#### 対策
HTTPレスポンスヘッダに **X-Content-Type-Options** 設定を付与します。
#### 対応方法
- Nginx

```nginx:nginx.conf
add_header X-Content-Type-Options nosniff;
```

- Apache

```apacheconf:httpd.conf
Header set X-Content-Type-Options nosniff
```


## X-Download-Optionsヘッダ
#### 説明
ユーザーがダウンロードしたファイルを直接「開く」ことを防止します。
#### 想定される脆弱性
ダウンロードしたファイルを直接「開く」ことにより、サーバをオリジンとしてコンテンツがブラウザ上で表示されるため蓄積型のクロスサイト・スクリプティング(XSS)攻撃が行われる可能性があります。
#### 対策
HTTPレスポンスヘッダに **X-Download-Options** 設定を付与します。
#### 対応方法
- Nginx

```nginx:nginx.conf
add_header X-Download-Options "noopen";
```

- Apache

```apacheconf:httpd.conf
Header set X-Download-Options: noopen
```

## OS, ソフトウェアのバージョン情報
#### 想定される脆弱性
バージョン情報がHTTPレスポンスヘッダーに含まれていることにより何らかの攻撃の手掛かりとなる恐れがあります。（ゼロデイ攻撃など）
#### 対策
バージョン情報を表示させないよう各種設定を付与します。
#### 対応方法
- Nginx

```nginx:nginx.conf
http {
    server_tokens off;
    ...
```

- Apache

```apacheconf:httpd.conf
ServerTokens ProductOnly
ServerSignature On
```

- PHP

```php:php.ini
expose_php = Off
```


## SSL設定
#### 想定される脆弱性
暗号方式（CipherSuite）の強度が弱いと、データ通信の盗聴や改ざんが行われる可能性があります。
#### 対策
情報処理推進機構（IPA）のｎ[SSL/TLS暗号設定ガイドライン](https://www.ipa.go.jp/security/vuln/ssl_crypt_config.html)に沿い、自身のサイトに合ったものを設定する。

Qualys SSL Labs社からもベストプラクティスが提示されています。
[SSL/TLS Deployment Best Practices](https://www.ssllabs.com/projects/best-practices/index.html)
#### 対応方法（参考）
- Nginx

```nginx:nginx.conf
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!EXPORT:!DES:!3DES:!MD5:!DSS;
```

- Apache

```apacheconf:httpd.conf
SSLProtocol ALL -SSLv3
SSLCipherSuite ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!EXPORT:!DES:!3DES:!MD5:!DSS
```
※Apache 2.4以降ではSSLv2が除外

## さいごに
対応方法として記載した設定情報についてはご自身のお使いの環境バージョンに応じて適宜読み替えてくださいm(_ _)m
またおすすめの設定があれば逐次記載していきたいと思います。