Add comprhensive csp polices and reporting endpoint. Add environment support require for protecting against rebinding attacks on ip addresses
This commit is contained in:
@@ -81,11 +81,37 @@ Rails.application.configure do
|
||||
config.active_record.attributes_for_inspect = [ :id ]
|
||||
|
||||
# Enable DNS rebinding protection and other `Host` header attacks.
|
||||
# config.hosts = [
|
||||
# "example.com", # Allow requests from example.com
|
||||
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
|
||||
# ]
|
||||
#
|
||||
# Configure allowed hosts based on deployment scenario
|
||||
allowed_hosts = [
|
||||
ENV.fetch('CLINCH_HOST', 'auth.aapamilne.com'), # External domain
|
||||
/.*#{ENV.fetch('CLINCH_HOST', 'aapamilne\.com').gsub('.', '\.')}/ # Subdomains
|
||||
]
|
||||
|
||||
# Allow Docker service names if running in same compose
|
||||
if ENV['CLINCH_DOCKER_SERVICE_NAME']
|
||||
allowed_hosts << ENV['CLINCH_DOCKER_SERVICE_NAME']
|
||||
end
|
||||
|
||||
# Allow internal IP access for cross-compose or host networking
|
||||
if ENV['CLINCH_ALLOW_INTERNAL_IPS'] == 'true'
|
||||
# Specific host IP
|
||||
allowed_hosts << '192.168.2.246'
|
||||
|
||||
# Private IP ranges for internal network access
|
||||
allowed_hosts += [
|
||||
/192\.168\.\d+\.\d+/, # 192.168.0.0/16 private network
|
||||
/10\.\d+\.\d+\.\d+/, # 10.0.0.0/8 private network
|
||||
/172\.(1[6-9]|2[0-9]|3[0-1])\.\d+\.\d+/ # 172.16.0.0/12 private network
|
||||
]
|
||||
end
|
||||
|
||||
# Local development fallbacks
|
||||
if ENV['CLINCH_ALLOW_LOCALHOST'] == 'true'
|
||||
allowed_hosts += ['localhost', '127.0.0.1', '0.0.0.0']
|
||||
end
|
||||
|
||||
config.hosts = allowed_hosts
|
||||
|
||||
# Skip DNS rebinding protection for the default health check endpoint.
|
||||
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||
config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||
end
|
||||
|
||||
@@ -4,26 +4,74 @@
|
||||
# See the Securing Rails Applications Guide for more information:
|
||||
# https://guides.rubyonrails.org/security.html#content-security-policy-header
|
||||
|
||||
# Rails.application.configure do
|
||||
# config.content_security_policy do |policy|
|
||||
# policy.default_src :self, :https
|
||||
# policy.font_src :self, :https, :data
|
||||
# policy.img_src :self, :https, :data
|
||||
# policy.object_src :none
|
||||
# policy.script_src :self, :https
|
||||
# policy.style_src :self, :https
|
||||
# # Specify URI for violation reports
|
||||
# # policy.report_uri "/csp-violation-report-endpoint"
|
||||
# end
|
||||
#
|
||||
# # Generate session nonces for permitted importmap, inline scripts, and inline styles.
|
||||
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
|
||||
# config.content_security_policy_nonce_directives = %w(script-src style-src)
|
||||
#
|
||||
# # Automatically add `nonce` to `javascript_tag`, `javascript_include_tag`, and `stylesheet_link_tag`
|
||||
# # if the corresponding directives are specified in `content_security_policy_nonce_directives`.
|
||||
# # config.content_security_policy_nonce_auto = true
|
||||
#
|
||||
# # Report violations without enforcing the policy.
|
||||
# # config.content_security_policy_report_only = true
|
||||
# end
|
||||
Rails.application.configure do
|
||||
config.content_security_policy do |policy|
|
||||
# Default policy: only allow resources from same origin and HTTPS
|
||||
policy.default_src :self, :https
|
||||
|
||||
# Scripts: strict security with nonce support for dynamic content
|
||||
policy.script_src :self, :https, :strict_dynamic
|
||||
|
||||
# Styles: allow inline styles for CSS frameworks, but require HTTPS
|
||||
policy.style_src :self, :https, :unsafe_inline
|
||||
|
||||
# Images: allow data URIs for inline images and HTTPS sources
|
||||
policy.img_src :self, :https, :data
|
||||
|
||||
# Fonts: allow self-hosted and HTTPS fonts, plus data URIs
|
||||
policy.font_src :self, :https, :data
|
||||
|
||||
# Media: allow self and HTTPS media sources
|
||||
policy.media_src :self, :https
|
||||
|
||||
# Objects: block potentially dangerous plugins
|
||||
policy.object_src :none
|
||||
|
||||
# Base URI: restrict base tag to same origin
|
||||
policy.base_uri :self
|
||||
|
||||
# Form actions: only allow forms to submit to same origin
|
||||
policy.form_action :self
|
||||
|
||||
# Frame ancestors: prevent clickjacking by disallowing framing
|
||||
policy.frame_ancestors :none
|
||||
|
||||
# Frame sources: block iframes unless explicitly needed
|
||||
policy.frame_src :none
|
||||
|
||||
# Connect sources: control where XHR/Fetch can connect
|
||||
policy.connect_src :self, :https
|
||||
|
||||
# Manifest: only allow same-origin manifest files
|
||||
policy.manifest_src :self
|
||||
|
||||
# Worker sources: control web worker origins
|
||||
policy.worker_src :self, :https
|
||||
|
||||
# Report URI: send violation reports to our monitoring endpoint
|
||||
if Rails.env.production?
|
||||
policy.report_uri "/api/csp-violation-report"
|
||||
end
|
||||
end
|
||||
|
||||
# Generate session nonces for permitted inline scripts and styles
|
||||
config.content_security_policy_nonce_generator = ->(request) {
|
||||
# Use a secure random nonce instead of session ID for better security
|
||||
SecureRandom.base64(16)
|
||||
}
|
||||
|
||||
# Apply nonces to script and style directives
|
||||
config.content_security_policy_nonce_directives = %w(script-src style-src)
|
||||
|
||||
# Automatically add `nonce` attributes to script/style tags
|
||||
config.content_security_policy_nonce_auto = true
|
||||
|
||||
# Enforce CSP in production, but use report-only in development for debugging
|
||||
if Rails.env.production?
|
||||
# Enforce the policy in production
|
||||
config.content_security_policy_report_only = false
|
||||
else
|
||||
# Report violations only in development (helps with debugging)
|
||||
config.content_security_policy_report_only = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,6 +31,7 @@ Rails.application.routes.draw do
|
||||
# ForwardAuth / Trusted Header SSO
|
||||
namespace :api do
|
||||
get "/verify", to: "forward_auth#verify"
|
||||
post "/csp-violation-report", to: "csp#violation_report"
|
||||
end
|
||||
|
||||
# Authenticated routes
|
||||
|
||||
Reference in New Issue
Block a user