Railsでセキュリティ用ヘッダをまとめて付与secureheaders[Gem]


secureheaders」はRuby on Railsのレスポンスにセキュリティに関する次のヘッダをまとめて設定してくれる便利なgemです。特にCSPなどを導入すると予期せぬスクリプトの混入を防いだり、mixed-contentを防止するのに役立ちます!


ヘッダ 説明
Content Security Policy XSS、mixed-content等の攻撃を検知・防止
HTTP Strict Transport Security HTTPSへのアクセスをブラウザに依頼
X-Frame-Option(XFO) <iframe><frame>タグでコンテンツを表示を制御
X-XSS-Protection クロスサイト・スクリプティングを緩和するためのフィルタ
X-Content-Type-Options nosniffでContent-Typeの意図しない改変を防ぎます
X-Download-Options noopenでDLしたファイルを直接開くことを防止します
X-Permitted-Cross-Domain-Policie Flashからのアクセスを制限します
Referrer-Policy リファラの送信の制御。no-referrerでreferrerを送信しない等
Public Key Pinning 偽造された証明書による中間攻撃を防ぐための設定
Clear-Site-Data ブラウザキャッシュの削除を依頼します

🐝 インストール手順

次のコードをGemfileに追加して、bundle installを実行してください。

# Security related headers
gem 'secure_headers'

🏀 設定

config/initializers/secure_headers.rbを作成して、サイトごとに必要な設定を追加してください。

SecureHeaders::Configuration.default do |config|
config.cookies = {
secure: true, # mark all cookies as "Secure"
httponly: true, # mark all cookies as "HttpOnly"
samesite: {
lax: true # mark all cookies as SameSite=lax
}
}
# Add "; preload" and submit the site to hstspreload.org for best protection.
config.hsts = "max-age=#{20.years.to_i}; includeSubdomains"
config.x_frame_options = "DENY"
config.x_content_type_options = "nosniff"
config.x_xss_protection = "1; mode=block"
config.x_download_options = "noopen"
config.x_permitted_cross_domain_policies = "none"
config.referrer_policy = "origin-when-cross-origin"
config.clear_site_data = [
"cache",
"cookies",
"storage",
"executionContexts"
]
config.csp = {
# "meta" values. these will shaped the header, but the values are not included in the header.
# report_only: true, # default: false [DEPRECATED from 3.5.0: instead, configure csp_report_only]
preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
# directive values: these values will directly translate into source directives
default_src: %w(https: 'self'),
base_uri: %w('self'),
block_all_mixed_content: true, # see http://www.w3.org/TR/mixed-content/
child_src: %w('self'), # if child-src isn't supported, the value for frame-src will be set.
connect_src: %w(wss:),
font_src: %w('self' data:),
form_action: %w('self' github.com),
frame_ancestors: %w('none'),
img_src: %w(mycdn.com data:),
media_src: %w(utoob.com),
object_src: %w('self'),
plugin_types: %w(application/x-shockwave-flash),
script_src: %w('self'),
style_src: %w('unsafe-inline'),
upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
report_uri: %w(https://report-uri.io/example-csp)
}
# This is available only from 3.5.0; use the `report_only: true` setting for 3.4.1 and below.
config.csp_report_only = config.csp.merge({
img_src: %w(somewhereelse.com),
report_uri: %w(https://report-uri.io/example-csp-report-only)
})
config.hpkp = {
report_only: false,
max_age: 60.days.to_i,
include_subdomains: true,
report_uri: "https://report-uri.io/example-hpkp",
pins: [
{sha256: "abc"},
{sha256: "123"}
]
}
end

🤔 デフォルトのヘッダ

デフォルトで設定されるヘッダは次のようになります。

Content-Security-Policy: default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
Strict-Transport-Security: max-age=631138519
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: sameorigin
X-Permitted-Cross-Domain-Policies: none
X-Xss-Protection: 1; mode=block

👽 参考リンク

📚 おすすめの書籍