Bug 15207 - mod_proxy alters URIs when acting as a reverse proxy
Summary: mod_proxy alters URIs when acting as a reverse proxy
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy (show other bugs)
Version: 2.0.43
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
: 18564 24873 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-12-10 01:58 UTC by Phil Gregory
Modified: 2015-07-11 03:05 UTC (History)
5 users (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Phil Gregory 2002-12-10 01:58:06 UTC
When a URI passes through mod_proxy, either via ProxyPass or a proxying
RewriteRule, mod_proxy appears to be decoding percent escaped characters before
passing the URI on to the destination server.  (So, for example, if the original
URI contains a "%2B", the destination server will see a "+".)

This is contrary to RFC 2616 (HTTP/1.1), which says 'A transparent proxy MUST
NOT rewrite the "abs_path" part of the received Request-URI when forwarding it
to the next inbound server, except as noted above to replace a null abs_path
with "/".' (section 5.1.2).  In addition, it breaks a CGI I'm using.  :)

As further information, the decoding seems to be recursive to a degree.  "%252B"
is also converted into "+", but "%25252B" merely becomes "%252B".
Comment 1 Zvi Har'El 2003-04-27 09:37:23 UTC
A reverse proxy doesn't need to be transparent. It may be as well a caching
proxy, that approached the backend server only if it doens't have a fresh copy
of the requested object. There fore, it MAY alter the URL. However, there is a
bug in this alteration: In the reverse proxy case, unescaping is done twice. In
the first   unesacping, the core does this for any non-proxy request. However,
this is done before reverse proxy requests are identified by matching the URL
with ProxyPass directives. Therefore, the second unescaping, in the function
ap_proxy_canonenc in proxy_util.c, should be done only for a standard proxy, and
not for a reverse proxy, and the line

if (isenc && ch == '%') {

(proxy_util.c:206 in httpd_2.0.45) should be replaced by

if (isenc == PROXYREQ_PROXY && ch == '%') {
Comment 2 Nick Kew 2004-06-26 14:50:26 UTC
*** Bug 24873 has been marked as a duplicate of this bug. ***
Comment 3 Nick Kew 2004-06-26 16:10:39 UTC
*** Bug 18564 has been marked as a duplicate of this bug. ***
Comment 4 Nick Kew 2004-06-29 06:47:18 UTC
Fix now committed to HEAD (subject to review)
Comment 5 Joshua Hirsh 2005-02-18 21:02:30 UTC
This bug still exists as of 2.0.53. The suggested patch in proxy_util.c from Zvi
Har'El, listed below, corrects the problem for me:

if (isenc == PROXYREQ_PROXY && ch == '%') {

To reproduce the bug, I setup a Reverse Proxy and use the following urls for
testing:

http://1.2.3.4/%		-Returns bad request
http://1.2.3.4/%25		-Works
http://1.2.3.4/proxy/%		-Returns bad request
http://1.2.3.4/proxy/%25	-Returns bad request

After the patch, the last example works properly.
Comment 6 Cahya 2005-05-24 18:30:59 UTC
I have also the same problem with apache 2.0.54, 
is there any plan to fix it in the next release?
thanks
Comment 7 Joe Orton 2005-08-05 16:02:29 UTC
Fixed for 2.0.55: http://svn.apache.org/viewcvs.cgi?rev=227435&view=rev