From: Tom Hughes Date: Sun, 26 Feb 2017 19:34:31 +0000 (+0000) Subject: Add support for Content-Security-Policy X-Git-Tag: live~3542 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/40a8e5caf5e5c69d175a90b81528d81d1e4e0964?hp=-c Add support for Content-Security-Policy Currently this is report only, and disabled unless a report URL has been set in the application configuration. --- 40a8e5caf5e5c69d175a90b81528d81d1e4e0964 diff --git a/.rubocop.yml b/.rubocop.yml index 477b2ab02..5bae96caa 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -62,3 +62,7 @@ Rails/SkipsModelValidations: Exclude: - 'db/migrate/*.rb' - 'app/controllers/user_controller.rb' + +Lint/PercentStringArray: + Exclude: + - 'config/initializers/secure_headers.rb' diff --git a/Gemfile b/Gemfile index 85f1a87e4..72fc32683 100644 --- a/Gemfile +++ b/Gemfile @@ -92,6 +92,9 @@ gem "rotp" gem "dalli" gem "kgio" +# Load secure_headers for Content-Security-Policy support +gem "secure_headers" + # Used to generate logstash friendly log files gem "logstasher" diff --git a/Gemfile.lock b/Gemfile.lock index c4891a358..b3768cb74 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -96,7 +96,7 @@ GEM globalid (0.3.7) activesupport (>= 4.1.0) hashdiff (0.3.2) - hashie (3.5.4) + hashie (3.5.5) htmlentities (4.3.4) http_accept_language (2.0.5) i18n (0.8.1) @@ -218,7 +218,7 @@ GEM websocket-driver (>= 0.2.0) powerpack (0.1.1) progress (3.3.1) - psych (2.2.3) + psych (2.2.4) public_suffix (2.0.5) r2 (0.2.6) rack (1.6.5) @@ -283,6 +283,8 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) + secure_headers (3.6.1) + useragent simplecov (0.12.0) docile (~> 1.1.0) json (>= 1.8, < 3) @@ -310,6 +312,7 @@ GEM uglifier (3.0.4) execjs (>= 0.3.0, < 3) unicode-display_width (1.1.3) + useragent (0.16.8) validates_email_format_of (1.6.3) i18n vendorer (0.1.16) @@ -376,6 +379,7 @@ DEPENDENCIES rubocop sanitize sass-rails (~> 5.0) + secure_headers timecop uglifier (>= 1.3.0) validates_email_format_of (>= 1.5.1) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8eb5f2409..10901fdd5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -407,6 +407,11 @@ class ApplicationController < ActionController::Base end def map_layout + append_content_security_policy_directives( + :connect_src => %w(nominatim.openstreetmap.org overpass-api.de router.project-osrm.org valhalla.mapzen.com), + :script_src => %w(graphhopper.com open.mapquestapi.com) + ) + request.xhr? ? "xhr" : "map" end diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index aa284ecdc..353feecef 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -69,6 +69,13 @@ class SiteController < ApplicationController require_user end + if editor == "potlatch" || editor == "potlatch2" + append_content_security_policy_directives( + :object_src => %w(*), + :plugin_types => %w(application/x-shockwave-flash) + ) + end + if params[:node] bbox = Node.find(params[:node]).bbox.to_unscaled @lat = bbox.centre_lat @@ -111,6 +118,12 @@ class SiteController < ApplicationController end def id + append_content_security_policy_directives( + :connect_src => %w(taginfo.openstreetmap.org *.mapillary.com), + :img_src => %w(*), + :script_src => %w(dev.virtualearth.net) + ) + render "id", :layout => false end diff --git a/config/example.application.yml b/config/example.application.yml index f322dbccf..ec6048521 100644 --- a/config/example.application.yml +++ b/config/example.application.yml @@ -119,6 +119,8 @@ defaults: &defaults #thunderforest_key: "" # Key for generating TOTP tokens #totp_key: "" + # URL for reporting Content-Security-Policy violations + #csp_report_url: "" development: <<: *defaults diff --git a/config/initializers/secure_headers.rb b/config/initializers/secure_headers.rb new file mode 100644 index 000000000..13db36509 --- /dev/null +++ b/config/initializers/secure_headers.rb @@ -0,0 +1,24 @@ +policy = if defined?(CSP_REPORT_URL) + { + :default_src => %w('self'), + :child_src => %w('self'), + :connect_src => %w('self'), + :font_src => %w('none'), + :form_action => %w('self'), + :frame_ancestors => %w('self'), + :img_src => %w('self' data: www.gravatar.com *.wp.com *.tile.openstreetmap.org *.tile.thunderforest.com *.openstreetmap.fr), + :media_src => %w('none'), + :object_src => %w('self'), + :plugin_types => %w('none'), + :script_src => %w('self' 'unsafe-inline'), + :style_src => %w('self' 'unsafe-inline'), + :report_uri => [CSP_REPORT_URL] + } + else + SecureHeaders::OPT_OUT + end + +SecureHeaders::Configuration.default do |config| + config.csp = SecureHeaders::OPT_OUT + config.csp_report_only = policy +end