Skip to content

Commit 268c340

Browse files
committed
Optionally allow ActionCable requests from the same host as origin
When the `allow_same_origin_as_host` is set to `true`, the request forgery protection permits `HTTP_ORIGIN` values starting with the corresponding `proto://` prefix followed by `HTTP_HOST`. This way it is not required to specify the list of allowed URLs.
1 parent 1996624 commit 268c340

File tree

4 files changed

+18
-1
lines changed

4 files changed

+18
-1
lines changed

actioncable/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ To disable and allow requests from any origin:
340340
Rails.application.config.action_cable.disable_request_forgery_protection = true
341341
```
342342

343+
It is also possible to allow origins that are starting with the actual HTTP HOST header:
344+
```ruby
345+
Rails.application.config.action_cable.allow_same_origin_as_host = true
346+
```
347+
343348
### Consumer Configuration
344349

345350
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.

actioncable/lib/action_cable/connection/base.rb

+3
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,11 @@ def send_welcome_message
195195
def allow_request_origin?
196196
return true if server.config.disable_request_forgery_protection
197197

198+
proto = Rack::Request.new(env).ssl? ? "https" : "http"
198199
if Array(server.config.allowed_request_origins).any? { |allowed_origin| allowed_origin === env["HTTP_ORIGIN"] }
199200
true
201+
elsif server.config.allow_same_origin_as_host && env["HTTP_ORIGIN"] == "#{proto}://#{env['HTTP_HOST']}"
202+
true
200203
else
201204
logger.error("Request origin not allowed: #{env['HTTP_ORIGIN']}")
202205
false

actioncable/lib/action_cable/server/configuration.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Server
55
class Configuration
66
attr_accessor :logger, :log_tags
77
attr_accessor :use_faye, :connection_class, :worker_pool_size
8-
attr_accessor :disable_request_forgery_protection, :allowed_request_origins
8+
attr_accessor :disable_request_forgery_protection, :allowed_request_origins, :allow_same_origin_as_host
99
attr_accessor :cable, :url, :mount_path
1010

1111
def initialize
@@ -15,6 +15,7 @@ def initialize
1515
@worker_pool_size = 4
1616

1717
@disable_request_forgery_protection = false
18+
@allow_same_origin_as_host = false
1819
end
1920

2021
# Returns constant of subscription adapter specified in config/cable.yml.

actioncable/test/connection/cross_site_forgery_test.rb

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def send_async(method, *args)
1818
teardown do
1919
@server.config.disable_request_forgery_protection = false
2020
@server.config.allowed_request_origins = []
21+
@server.config.allow_same_origin_as_host = false
2122
end
2223

2324
test "disable forgery protection" do
@@ -53,6 +54,13 @@ def send_async(method, *args)
5354
assert_origin_not_allowed "http://rails.co.uk"
5455
end
5556

57+
test "allow same origin as host" do
58+
@server.config.allow_same_origin_as_host = true
59+
assert_origin_allowed "http://#{HOST}"
60+
assert_origin_not_allowed "http://hax.com"
61+
assert_origin_not_allowed "http://rails.co.uk"
62+
end
63+
5664
private
5765
def assert_origin_allowed(origin)
5866
response = connect_with_origin origin

0 commit comments

Comments
 (0)