diff options
author | Matthew Draper <matthew@trebex.net> | 2016-10-11 12:28:38 +1030 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2016-10-11 12:28:38 +1030 |
commit | f8c53eff7be9a5670e3c0da5851312977becb308 (patch) | |
tree | 280b4a0070cbc7a275ca79eaf3bd1bcf298697da | |
parent | bc9dc418259f1db0f14ed895e8469b7839ef474b (diff) | |
parent | 268c340b0909bd78259e58b1ed0b53133d924199 (diff) | |
download | rails-f8c53eff7be9a5670e3c0da5851312977becb308.tar.gz rails-f8c53eff7be9a5670e3c0da5851312977becb308.tar.bz2 rails-f8c53eff7be9a5670e3c0da5851312977becb308.zip |
Merge pull request #26568 from skateman/cable-sameorigin-as-host
Optionally allow ActionCable requests from the same host as origin
-rw-r--r-- | actioncable/README.md | 5 | ||||
-rw-r--r-- | actioncable/lib/action_cable/connection/base.rb | 3 | ||||
-rw-r--r-- | actioncable/lib/action_cable/server/configuration.rb | 3 | ||||
-rw-r--r-- | actioncable/test/connection/cross_site_forgery_test.rb | 8 |
4 files changed, 18 insertions, 1 deletions
diff --git a/actioncable/README.md b/actioncable/README.md index a0b7412dd4..30b86edd2e 100644 --- a/actioncable/README.md +++ b/actioncable/README.md @@ -340,6 +340,11 @@ To disable and allow requests from any origin: Rails.application.config.action_cable.disable_request_forgery_protection = true ``` +It is also possible to allow origins that are starting with the actual HTTP HOST header: +```ruby +Rails.application.config.action_cable.allow_same_origin_as_host = true +``` + ### Consumer Configuration Once you have decided how to run your cable server (see below), you must provide the server URL (or path) to your client-side setup. diff --git a/actioncable/lib/action_cable/connection/base.rb b/actioncable/lib/action_cable/connection/base.rb index 06f4f5edd3..2596635701 100644 --- a/actioncable/lib/action_cable/connection/base.rb +++ b/actioncable/lib/action_cable/connection/base.rb @@ -195,8 +195,11 @@ module ActionCable def allow_request_origin? return true if server.config.disable_request_forgery_protection + proto = Rack::Request.new(env).ssl? ? "https" : "http" if Array(server.config.allowed_request_origins).any? { |allowed_origin| allowed_origin === env["HTTP_ORIGIN"] } true + elsif server.config.allow_same_origin_as_host && env["HTTP_ORIGIN"] == "#{proto}://#{env['HTTP_HOST']}" + true else logger.error("Request origin not allowed: #{env['HTTP_ORIGIN']}") false diff --git a/actioncable/lib/action_cable/server/configuration.rb b/actioncable/lib/action_cable/server/configuration.rb index dc146f07b0..aa8d10b3d4 100644 --- a/actioncable/lib/action_cable/server/configuration.rb +++ b/actioncable/lib/action_cable/server/configuration.rb @@ -5,7 +5,7 @@ module ActionCable class Configuration attr_accessor :logger, :log_tags attr_accessor :connection_class, :worker_pool_size - attr_accessor :disable_request_forgery_protection, :allowed_request_origins + attr_accessor :disable_request_forgery_protection, :allowed_request_origins, :allow_same_origin_as_host attr_accessor :cable, :url, :mount_path def initialize @@ -15,6 +15,7 @@ module ActionCable @worker_pool_size = 4 @disable_request_forgery_protection = false + @allow_same_origin_as_host = false end # Returns constant of subscription adapter specified in config/cable.yml. diff --git a/actioncable/test/connection/cross_site_forgery_test.rb b/actioncable/test/connection/cross_site_forgery_test.rb index 3bc59c9db9..6cabff5440 100644 --- a/actioncable/test/connection/cross_site_forgery_test.rb +++ b/actioncable/test/connection/cross_site_forgery_test.rb @@ -18,6 +18,7 @@ class ActionCable::Connection::CrossSiteForgeryTest < ActionCable::TestCase teardown do @server.config.disable_request_forgery_protection = false @server.config.allowed_request_origins = [] + @server.config.allow_same_origin_as_host = false end test "disable forgery protection" do @@ -53,6 +54,13 @@ class ActionCable::Connection::CrossSiteForgeryTest < ActionCable::TestCase assert_origin_not_allowed "http://rails.co.uk" end + test "allow same origin as host" do + @server.config.allow_same_origin_as_host = true + assert_origin_allowed "http://#{HOST}" + assert_origin_not_allowed "http://hax.com" + assert_origin_not_allowed "http://rails.co.uk" + end + private def assert_origin_allowed(origin) response = connect_with_origin origin |