Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
such as squid which we do on drupal.org.
We need to optionally check the http://en.wikipedia.org/wiki/X-Forwarded-For header in flood is allowed.
Comment | File | Size | Author |
---|---|---|---|
#32 | proxy-5.patch | 13.19 KB | kbahey |
#29 | proxy_4.patch | 13.28 KB | kbahey |
#21 | proxy_3.patch | 13.21 KB | kbahey |
#14 | proxy_2.patch | 12.83 KB | kbahey |
#12 | proxy_1.patch | 12.23 KB | kbahey |
Comments
Comment #1
kbahey CreditAttribution: kbahey commentedThis is a good idea.
However, does this idea need to be expanded more for other uses of the IP address?
I can see that
$_SERVER['REMOTE_ADDR']
is used in many places in these files in core:includes/bootstrap.inc
includes/common.inc
includes/session.inc
modules/comment/comment.module
modules/poll/poll.module
modules/statistics/statistics.module
Not to mention contrib.
So, perhaps we need to have a Drupal specific variable called $drupal_ip_address or something that all modules can use. The raw HTTP variables will still be there if a module needs it.
If others agree on this, then I can work on it. The issue title will need to change too.
Comment #2
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedI think "now working behind reverse proxies" will make a nice feature for D6.
Comment #3
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedKhalid, will you work on it? Otherwise we'd need another volunteer with the code freeze looming.
Currently, the "disable access by IP" function on drupal.org is completely broken due to this.
Changing title and priority.
Comment #4
kbahey CreditAttribution: kbahey commentedAssigning to myself.
Gerhard, can you please run this script from a browser on any machine on *.d.o that is using FCGI?
Email me privately if you see anything that is sensitive.
Comment #5
kbahey CreditAttribution: kbahey commentedFound an older issue for this. Says that the header can be spoofed.
http://drupal.org/node/20471
Comment #6
kbahey CreditAttribution: kbahey commentedHere is a patch that should be portable. It does NOT require PHP as an Apache module unlike the previous patch (linked above), and will work with PHP as an FCGI.
What it does is replace all occurances of $_SERVER['REMOTE_ADDR'] with a call to the new remote_addr() function. remote_addr() checks if we have an X-Forwarded-For header, and takes the IP address in it. Otherwise, REMOTE_ADDR will be used.
I am not sure if filter_xss() is needed here or not. I left it in just in case.
Comment #7
kbahey CreditAttribution: kbahey commentedUmm, it always helps if you have patches that actually work.
Here is one that at least does not produce errors.
If someone with ssh access can create a D6 site on drupal1 or drupal2, and install this patch and verify that the correct IP address is used in the session, comment, watchdog, poll and statistics modules.
Comment #8
Dries CreditAttribution: Dries commentedLooks good, but can we rename remote_addr() to remote_address() or ip_address() ? We try not to abbreviate simple words. Thanks.
should probably be part of the PHPdoc, rathern than an inline comment. I'd replace 'straight IP address' with the name of the actual header.
In the documentation, it would be great if we could mention the RFC that documents this behavior, although this is really, really minor.
Also, as per Gerhard's suggestion, we'll want to add an entry to the CHANGELOG.txt.
Comment #9
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedKhalid, I've applied your patch on scratch.d.o. One problem was that filter_xss is not yet defined when you define remote_addr.
Comment #10
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedI've looked into the sessions and the comments table abd the patch seems to work fine (after removing the filter_xss call).
However, with the logic in remote_addr it is now very easy to bypass our access control: Simply pass some X-forwarded-by header.
Comment #11
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedI've looked into the sessions and the comments table abd the patch seems to work fine (after removing the filter_xss call).
However, with the logic in remote_addr it is now very easy to bypass our access control: Simply pass some X-forwarded-by header.
Comment #12
kbahey CreditAttribution: kbahey commentedHere is an updated version.
- Added a new settings (under performance) that makes this explicit, to avoid header injection
- Changed function name to ip_address()
- Added a few missing places (in poll.module)
- Removed the check_plain, in accordance with the policy of filter on output, not input
- Added comment in CHANGELOG.txt
Comment #13
Dries CreditAttribution: Dries commentedThis text seems redudant:
The form description has typos/errors -- it doesn't read well.
Either way, we need to keep in mind that the majority of the Drupal users have never heard about a "reverse proxy". For them, this settings will be super-confusing. I suggest we make add a short description of what a "reverse proxy" is, how they can figure out whether they are using one, and a "if unsure, disable this feature or it might open up a security hole" style message. To make a long story short: let's make this a bit easier to grok for people like our mothers. ;-)
We need to sanitize the X-Forwarded-For header: see http://osvdb.org/displayvuln.php?osvdb_id=23480 and http://secunia.com/advisories/18930/. I think we do this on output, but it might be good to double-check.
According to http://en.wikipedia.org/wiki/X-Forwarded-For, the X-Forwarded-For header can be a comma-separated list of IP addresses. Looks like the code isn't capable of handling that scenario.
Comment #14
kbahey CreditAttribution: kbahey commentedDries,
Remember that proxies can be implemented in two places. One is at the client side (e.g. an organization wants to cache content for users to reduce traffic, like AOL does), or server side (like we do with Drupal.org).
Anyways, your suggestions are implemented in this version of the patch.
- Better documentation for the user.
- Updated CHANGELOG.txt
- Use check_plain() on the address.
- Use the leftmost argument only.
Comment #15
kbahey CreditAttribution: kbahey commentedkilles,
If you can test this patch on s.d.o, that would be great.
Comment #16
Dries CreditAttribution: Dries commentedkbahey: that will be a lot easier to grok for Joe Average. Thanks.
I'll wait for Gerhard to test this, and maybe for other people to suggest more subtle but important textual improvements. The code itself looks RTBC.
Comment #17
keith.smith CreditAttribution: keith.smith commentedI'm sorry I don't have time to do a more complete review or to roll a modified patch right now, but I'm posting this slightly modified text in the hopes it may help.
Original:
In some cases involving large sites, Drupal may be running behind a reverse proxy. A reverse proxy is used to enhance the performance of heavily visited sites, and is normally used in dedicated hosting or multi-server environment. Examples are Squid and Pound. This setting lets Drupal examine the X-Forwarded-For headers and use the correct IP address of the remote client. The IP address of the remote client is used in various parts of Drupal, such as sessions, watchdog, poll, statistics and comments. If you are sure that Drupal is running to be behind a reverse proxy, enable this option. If you are on a shared host, or do not know what a reverse proxy is, then it is safe to keep this setting disabled.
Modified:
Enable this setting to determine the correct IP address of the remote client by examining information stored in the X-Forwarded-For headers. X-Forwarded-For headers are a standard mechanism for identifying client systems connecting through a reverse proxy server; reverse proxy servers are often used to enhance the performance of heavily visited sites and may also provide other site caching, security or encryption benefits. If this Drupal installation operates behind a reverse proxy, this setting should be enabled so that correct IP address information is captured in Drupal's session management, logging, statistics and access management systems; if you are unsure about this setting, or Drupal operates in a shared hosting environment, this setting should be disabled.
Comment #18
kbahey CreditAttribution: kbahey commentedSlight modifications to Keith's version:
Enable this setting to determine the correct IP address of the remote client by examining information stored in the X-Forwarded-For headers. X-Forwarded-For headers are a standard mechanism for identifying client systems connecting through a reverse proxy server; such as Squid or Pound. Reverse proxy servers are often used to enhance the performance of heavily visited sites and may also provide other site caching, security or encryption benefits. If this Drupal installation operates behind a reverse proxy, this setting should be enabled so that correct IP address information is captured in Drupal's session management, logging, statistics and access management systems; if you are unsure about this setting, do not have a reverse proxy, or Drupal operates in a shared hosting environment, this setting should be set to disabled.
Any other English speakers who want to chip in? Angie?
Comment #19
keith.smith CreditAttribution: keith.smith commented(hit refresh as I was walking out the door).
Even better. Looks good, with the small nitpick that "reverse proxy server; such as Squid or Pound." should probably be "reverse proxy server, such as Squid or Pound." with a comma rather than a semicolon.
Comment #20
erdemkose CreditAttribution: erdemkose commentedI've never used reverse proxy, I can't test the patch but I want to say something about the code.
$remote_ip
should be static.array_key_exists
andisset
but I thinkisset
is faster and works same here.Comment #21
kbahey CreditAttribution: kbahey commentedHere is a version that implements Keith's wording improvements, as well as Erdem's suggestions.
I did not bother with isset() though, since now we only hit this code once per request, so the difference would be negligible.
Patch attached.
killes or dww, if you can try it on s.d.o that would be great.
Comment #22
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedPatch is installed and the setting is enabled.
Comment #23
kbahey CreditAttribution: kbahey commentedCool. Is that on d.o or s.d.o?
Comment #24
killes@www.drop.org CreditAttribution: killes@www.drop.org commenteds.d.o
Comment #25
kbahey CreditAttribution: kbahey commentedCan you say it is RTBC?
Any one else willing to test this?
Comment #26
Dries CreditAttribution: Dries commentedFew people will be able to test this patch. If we're using it on drupal.org and that seems to work, we should be OK. I'm willing to commit it, and if it breaks, we can still fix it later on. :)
Comment #27
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedThere's a typo in one of the comments but that shouldn't stop us.
Comment #28
Dries CreditAttribution: Dries commentedPatch no longer applies. Needs to be re-rolled.
Comment #29
kbahey CreditAttribution: kbahey commentedRerolled against today's HEAD.
Comment #30
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedcleanly applies now.
Comment #31
Dries CreditAttribution: Dries commentedActually, there is a conflict in the patch -- look at the last blob.
Comment #32
kbahey CreditAttribution: kbahey commentedRerolled against current HEAD.
Comment #33
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks! :)
Comment #34
hass CreditAttribution: hass commentedThis topic came to my radar, so i will give some more input... i've missed many more PROXY checks... here is a more complete list of variables available on the net...
Sorry, the following is perl logic with regex... but it gives you and idea what is required to check. the order is impotant... the order or regex is important and will use the last match as the real client IP. Additional the committed patch misses SSL check. if SSL is active we don't need to check any proxy vars... i cannot see anything about this in the code (short review only).
Comment #35
kbahey CreditAttribution: kbahey commentedhass,
The patch is designed for the case where Drupal itself is running BEHIND a reverse proxy, not when the CLIENT is behind a proxy server.
In this case, the sysadmin is sure of the situation and that indeed a proxy is in front of the server. In case of a client, these headers can be easily forged.
There are other issues about proxies in general, please search for them and post your comment there.
Comment #36
(not verified) CreditAttribution: commentedComment #37
Gerhard Killesreiter CreditAttribution: Gerhard Killesreiter commentedThe implementation chosen here was buggy, see http://drupal.org/node/169263
Comment #38
clustermagnet CreditAttribution: clustermagnet commentedGuys, could someone please comment: https://drupal.org/node/1358312
not able to front a drupal site via proxypass and proxypassreverse
Thanks!