cloudflare-rails 6.1.0 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '079b27f2bb751ae57b6ba12fa77c04abe62900241146ad7163b5c1f354a6a7a5'
4
- data.tar.gz: 820820c94a3e782deae3ed94d67d9cc145c976b0a82fa313ee448e8f29708e3b
3
+ metadata.gz: 6744917646a84fbd4d06faabf47537911ebc59369ab4848c0a3e9979ee21116e
4
+ data.tar.gz: 7bf4fc1daee7eb7101056eb3ab18d765ccfccbe5b8c02608f65daced10d0f49b
5
5
  SHA512:
6
- metadata.gz: a50b5891b48031f1a8a92ebfd08d63f4196df71abb14b5b4d24ab283f81170e3a68c6e04440d27a4c6ad7180030125bbbcff94ba708590536407b72b836acf82
7
- data.tar.gz: 1bbfa4fd1c77980454d38c76cb9c9ec1da912ada1460d0554d4b1da534a41c3e8e1022876b9090c6161223ecfcf61ddd1ce9868cd6654dab7eeba3b34fd81c06
6
+ metadata.gz: 49816d30c9ef0c1b59aac36eb59d4a30465d285e0426ed7a1c3b41439910acb2ab4c0f71c2d7f4fa90a5c02baba2ad58b23338b446120c6c4b078d691cede797
7
+ data.tar.gz: 2121fa3a384f1d3630cb0f87bd2a40bb6228ad2a5defa8fddad514c6b84c9cca37e19bc50bbdbf69e4fdee43966ba7cd8e7fb53f109176e8a45e1df3d63e0cf9
data/CHANGELOG.md CHANGED
@@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+ ## [6.2.0]
7
+ - Trust X-Forwarded-For from the right to the left (https://github.com/modosc/cloudflare-rails/pull/162)
8
+
6
9
  ## [6.1.0]
7
10
  - Add cloudflare? method to determine if request passed through CF (https://github.com/modosc/cloudflare-rails/pull/149)
8
11
 
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # CloudflareRails [![Gem Version](https://badge.fury.io/rb/cloudflare-rails.svg)](https://badge.fury.io/rb/cloudflare-rails)
2
+
2
3
  This gem correctly configures Rails for [CloudFlare](https://www.cloudflare.com) so that `request.remote_ip` / `request.ip` both work correctly. It also exposes a `#cloudflare?` method on `Rack::Request`.
3
4
 
4
5
  ## Rails Compatibility
@@ -38,9 +39,11 @@ Using Cloudflare means it's hard to identify the IP address of incoming requests
38
39
  `cloudflare-rails` mitigates this attack by checking that the originating ip address of any incoming connection is from one of Cloudflare's ip address ranges. If so, the incoming `X-Forwarded-For` header is trusted and used as the ip address provided to `rack` and `rails` (via `request.ip` and `request.remote_ip`). If the incoming connection does not originate from a Cloudflare server then the `X-Forwarded-For` header is ignored and the actual remote ip address is used.
39
40
 
40
41
  ## How it works
42
+
41
43
  This code fetches and caches CloudFlare's current [IPv4](https://www.cloudflare.com/ips-v4) and [IPv6](https://www.cloudflare.com/ips-v6) lists. It then patches `Rack::Request::Helpers` and `ActionDispatch::RemoteIP` to treat these addresses as trusted proxies. The `X-Forwarded-For` header will then be trusted only from those ip addresses.
42
44
 
43
45
  ### Why not use `config.action_dispatch.trusted_proxies` or `Rack::Request.ip_filter?`
46
+
44
47
  By default Rails includes the [ActionDispatch::RemoteIp](https://api.rubyonrails.org/classes/ActionDispatch/RemoteIp.html) middleware. This middleware uses a default list of [trusted proxies](https://github.com/rails/rails/blob/6b93fff8af32ef5e91f4ec3cfffb081d0553faf0/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L36C5-L42). Any values from `config.action_dispatch.trusted_proxies` are appended to this list. If you were to set `config.action_dispatch.trusted_proxies` to the current list of Cloudflare IP addresses `request.remote_ip` would work correctly.
45
48
 
46
49
  Unfortunately this does not fix `request.ip`. This method comes from the [Rack::Request](https://github.com/rack/rack/blob/main/lib/rack/request.rb) middleware. It has a separate implementation of [trusted proxies](https://github.com/rack/rack/blob/main/lib/rack/request.rb#L48-L56) and [ip filtering](https://github.com/rack/rack/blob/main/lib/rack/request.rb#L58C1-L59C1). The only way to use a different implementation is to set `Rack::Request.ip_filter` which expects a callable value. Providing a new one will override the old one so you'd lose the default values (all of which should be there). Those values aren't exported anywhere so your callable would now have to maintain _that_ list on top of the Cloudflare IPs.
@@ -48,33 +51,36 @@ Unfortunately this does not fix `request.ip`. This method comes from the [Rack::
48
51
  These issues are why this gem patches both `Rack::Request::Helpers` and `ActionDispatch::RemoteIP` rather than using the built-in configuration methods.
49
52
 
50
53
  ## Prerequisites
54
+
51
55
  You must have a [`cache_store`](https://guides.rubyonrails.org/caching_with_rails.html#configuration) configured in your `rails` application.
52
56
 
53
57
  ## Usage
58
+
54
59
  You can configure the HTTP `timeout` and `expires_in` cache parameters inside of your `rails` config:
60
+
55
61
  ```ruby
56
62
  config.cloudflare.expires_in = 12.hours # default value
57
63
  config.cloudflare.timeout = 5.seconds # default value
58
64
  ```
59
65
 
60
66
  ## Blocking non-Cloudflare traffic
61
- You can use the `#cloudfront?` method from this gem to block all non-Cloudflare traffic to your application. Here's an example of doing this with [`Rack::Attack`](https://github.com/rack/rack-attack):
67
+
68
+ You can use the `#cloudflare?` method from this gem to block all non-Cloudflare traffic to your application. Here's an example of doing this with [`Rack::Attack`](https://github.com/rack/rack-attack):
69
+
62
70
  ```ruby
63
71
  Rack::Attack.blocklist('CloudFlare WAF bypass') do |req|
64
72
  !req.cloudflare?
65
73
  end
66
74
  ```
67
- Note that the request may optionally pass through additional trusted proxies, so it will return true for any of these scenarios:
68
-
69
- * `REMOTE_ADDR: CloudFlare`
70
- * `REMOTE_ADDR: trusted_proxy`, `X_HTTP_FORWARDED_FOR: CloudFlare`
71
- * `REMOTE_ADDR: trusted_proxy`, `X_HTTP_FORWARDED_FOR: trusted_proxy2,CloudFlare,...`
72
75
 
73
- but it will return false if CloudFlare comes after the trusted prefix of `X-Forwarded-For`.
76
+ Note that the request may optionally pass through additional trusted proxies, so it will return `true` for any of these scenarios:
74
77
 
75
- ## Alternatives
78
+ - `REMOTE_ADDR: CloudFlare`
79
+ - `REMOTE_ADDR: trusted_proxy`, `X_HTTP_FORWARDED_FOR: CloudFlare`
80
+ - `REMOTE_ADDR: trusted_proxy`, `X_HTTP_FORWARDED_FOR: CloudFlare,trusted_proxy2`
81
+ - `REMOTE_ADDR: trusted_proxy`, `X_HTTP_FORWARDED_FOR: untrusted,CloudFlare`
76
82
 
77
- [actionpack-cloudflare](https://github.com/customink/actionpack-cloudflare) simpler approach using the `CF-Connecting-IP` header.
83
+ but it will return `false` if CloudFlare comes to the left of an untrusted IP in `X-Forwarded-For`.
78
84
 
79
85
  ## Development
80
86
 
@@ -27,9 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'rubocop', '~> 1.66.1'
28
28
  spec.add_development_dependency 'rubocop-performance', '~> 1.22.1'
29
29
  spec.add_development_dependency 'rubocop-rails', '~> 2.26.1'
30
- spec.add_development_dependency 'rubocop-rspec', '~> 3.0.1'
31
- spec.add_development_dependency 'webmock', '~> 3.23.1'
32
-
30
+ spec.add_development_dependency 'rubocop-rspec', '~> 3.1.0'
31
+ spec.add_development_dependency 'webmock', '~> 3.24.0'
33
32
  spec.add_dependency 'actionpack', '>= 7.1.0', '< 8.1.0'
34
33
  spec.add_dependency 'activesupport', '>= 7.1.0', '< 8.1.0'
35
34
  spec.add_dependency 'railties', '>= 7.1.0', '< 8.1.0'
@@ -20,7 +20,7 @@ module CloudflareRails
20
20
  forwarded_for = self.forwarded_for || []
21
21
 
22
22
  # Select only the trusted prefix of REMOTE_ADDR + X_HTTP_FORWARDED_FOR
23
- trusted_proxies = (remote_addresses + forwarded_for).take_while do |ip|
23
+ trusted_proxies = (remote_addresses + forwarded_for.reverse).take_while do |ip|
24
24
  trusted_proxy?(ip)
25
25
  end
26
26
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudflareRails
4
- VERSION = '6.1.0'
4
+ VERSION = '6.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudflare-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 6.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jonathan schatz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-23 00:00:00.000000000 Z
11
+ date: 2024-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -156,28 +156,28 @@ dependencies:
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: 3.0.1
159
+ version: 3.1.0
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: 3.0.1
166
+ version: 3.1.0
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: webmock
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: 3.23.1
173
+ version: 3.24.0
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: 3.23.1
180
+ version: 3.24.0
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: actionpack
183
183
  requirement: !ruby/object:Gem::Requirement