-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cloudflare? method to determine if request passed through CF #149
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The `request.cloudflare?` method can be used in a Rack::Attack blocklist rule to block traffic that hasn't passed through CloudFlare. For instance: ```ruby Rack::Attack.blocklist('CloudFlare WAF bypass') do |req| !req.cloudflare? end ``` Note that the request may optionally pass through additional trusted proxies, so it will return true for any of these scenarios: * `REMOTE_ADDR` = CloudFlare * `REMOTE_ADDR` = *trusted_proxy*, `X_HTTP_FORWARDED_FOR` = CloudFlare,... * `REMOTE_ADDR` = *trusted_proxy*, `X_HTTP_FORWARDED_FOR` = *trusted_proxy2*,CloudFlare,... but it will return false if CloudFlare comes after the trusted prefix of `X-Forwarded-For`.
modosc
requested changes
Aug 31, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is great, thanks!
please fix the linter issues and we're good. i'll update the README.md
with docs around this functionality after this lands.
* Break up tests to only have one expectation per spec * Reduce line lengths
Thanks for the quick reply! Rubocop warnings are fixed. |
geoffharcourt
added a commit
to geoffharcourt/cloudflare-rails
that referenced
this pull request
Oct 4, 2024
In modosc#149 we got the extremely helpful `Request#cloudflare?` method which can assist with checking if a request has been proxied through Cloudflare. The method checks that there's an unbroken chain of trust from the `REMOTE_ADDR` (if it exists) through forwarded IPs that only includes trusted internal proxies and Cloudflare IP addresses. Each proxy in the chain is supposed to append the IP of the traffic it received to the *right side* of `X-Forwarded-For`. This means that after evaluating `REMOTE_ADDR` we should be looking at addresses in `X-Forwarded-For` starting on the right side, not on the left. https://github.com/modosc/cloudflare-rails/blob/311875eef57862ecf050fb87415c56ea4823486a/lib/cloudflare_rails/check_trusted_proxies.rb#L23-L25 This ordering means that if a request has the original client as the first address in `X-Forwarded-For` that we'll incorrectly reject it. It also means that an attacker could craft a forged `X-Forwarded-For` that starts with a Cloudflare IP and smuggle in a request that appears to be valid to the method's logic. The fix here is to continue to look at `REMOTE_ADDR` first but then to look at `X-Forwarded-For` in right-to-left order until we run out of trusted IP addresses (whether internal proxies or Cloudflare IPs). Fix modosc#161
modosc
pushed a commit
that referenced
this pull request
Oct 7, 2024
In #149 we got the extremely helpful `Request#cloudflare?` method which can assist with checking if a request has been proxied through Cloudflare. The method checks that there's an unbroken chain of trust from the `REMOTE_ADDR` (if it exists) through forwarded IPs that only includes trusted internal proxies and Cloudflare IP addresses. Each proxy in the chain is supposed to append the IP of the traffic it received to the *right side* of `X-Forwarded-For`. This means that after evaluating `REMOTE_ADDR` we should be looking at addresses in `X-Forwarded-For` starting on the right side, not on the left. https://github.com/modosc/cloudflare-rails/blob/311875eef57862ecf050fb87415c56ea4823486a/lib/cloudflare_rails/check_trusted_proxies.rb#L23-L25 This ordering means that if a request has the original client as the first address in `X-Forwarded-For` that we'll incorrectly reject it. It also means that an attacker could craft a forged `X-Forwarded-For` that starts with a Cloudflare IP and smuggle in a request that appears to be valid to the method's logic. The fix here is to continue to look at `REMOTE_ADDR` first but then to look at `X-Forwarded-For` in right-to-left order until we run out of trusted IP addresses (whether internal proxies or Cloudflare IPs). Fix #161
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The
request.cloudflare?
method can be used in a Rack::Attack blocklist rule to block traffic that hasn't passed through CloudFlare.For instance:
Note that the request may optionally pass through additional trusted proxies, so it will return true for any of these scenarios:
REMOTE_ADDR
= CloudFlareREMOTE_ADDR
= trusted_proxy,X_HTTP_FORWARDED_FOR
= CloudFlare,...REMOTE_ADDR
= trusted_proxy,X_HTTP_FORWARDED_FOR
= trusted_proxy2,CloudFlare,...but it will return false if CloudFlare comes after the trusted prefix of
X-Forwarded-For
.