Add support for Content-Security-Policy
authorTom Hughes <tom@compton.nu>
Sun, 26 Feb 2017 19:34:31 +0000 (19:34 +0000)
committerTom Hughes <tom@compton.nu>
Sun, 26 Feb 2017 19:48:13 +0000 (19:48 +0000)
Currently this is report only, and disabled unless a report URL has
been set in the application configuration.

.rubocop.yml
Gemfile
Gemfile.lock
app/controllers/application_controller.rb
app/controllers/site_controller.rb
config/example.application.yml
config/initializers/secure_headers.rb [new file with mode: 0644]

index 477b2ab..5bae96c 100644 (file)
@@ -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 85f1a87..72fc326 100644 (file)
--- 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"
 
index c4891a3..b3768cb 100644 (file)
@@ -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)
index 8eb5f24..10901fd 100644 (file)
@@ -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
 
index aa284ec..353feec 100644 (file)
@@ -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
 
index f322dbc..ec60485 100644 (file)
@@ -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 (file)
index 0000000..13db365
--- /dev/null
@@ -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