I'm using a backend server behind a ProxyPass and a ProxyPassReverse. When the URL contains a %3A (encoded colon :) this %3A is passed to the backend as : instead of being kept as %3A, which yields an invalid URL and confuses the backend. When the URL contains a %2F (encoded slash /), mod_proxy becomes quite confused, and yields a 404 without even consulting the backend.
Tested with apache 1.3.26-0woody3 from debian as well as with a libproxy recompiled from the 1.3.31-1 source package from debian. Relevant lines from httpd.conf: ProxyPass / http://my.server.fqdn:8000/ ProxyPassReverse / http://my.server.fqdn:8000/
While trying to isolate the bug, I found that the : behaviour went wrong when apache is listening on port 80, but not when it is listening to port 8000. The way things are handled seem quite messy -- walking to the first : in a decoded URL? Note that the symptoms are vaguely similar to those of bug 11265, though the internal details differ.
The problem seems to be in the URL "canonicalization" happening in proxy_http.c:ap_proxy_http_canon, as called from mod_proxy.c:proxy_fixup. I can't fix it right now, because I don't understand the ins and outs of the proxy protocol: particularly, the GET http://foo.bar/baz HTTP/0.9 is one thing, and GET /baz HTTP/1.1 Host: foo.bar is another, but there are other cases. Can anyone point me to a document that explains this part of the protocol?
Created attachment 11856 [details] Fix for ProxyPass with encoded : and /
OK. There were two bugs involved. The port 80/8000 thing might have had to do with my incorrectly tweaking httpd.conf during testing, so let's forget it. The problem with %3A ':' was due to a misguided URI canonicalization attempt in function modules/proxy/mod_proxy.c:proxy_fixup(). I added a bypass to the canonicalization in the case of PROXY_PASS. Actually I believe canonicalization shouldn't happen in the STD_PROXY case either and the whole function should be scrapped. The problem with %2F '/' was due to r->proxyreq=PROXY_PASS being declared too late, only in modules/proxy/mod_proxy.c:proxy_trans(), so that main/http_request.c:process_request_internal() messed up with the URL, not realizing there is a proxy request going on. Consequently, I moved the stuff from modules/proxy/mod_proxy.c:proxy_trans() into modules/proxy/mod_proxy.c:proxy_detect(). PS: note that so as to compile mod_proxy from apache 1.3.31 on my old apache 1.3.26, I had to add this to mod_proxy.h: #define ap_psocket_ex(p,q,r,s,t) (t==1?ap_psocket(p,q,r,s):-1) THE HORROR! THE HORROR!
Oops. A stupid bug in my previous patch (forgot to return DECLINED; in proxy_trans()) broke everything outside of the proxy. Fixed in the following patch...
Created attachment 11858 [details] Fix ProxyPass AND not break everything else.
Looking at the sources for apache 2.0.49, I can see that the same bug is there, too.
Final notes: My debugging tool was to have LogLevel debug in the proper VirtualHost, and to add the following macro to mod_proxy.h #define DEBUGMSG(FMT...) \ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO,r,FMT) In Apache 2, the bug is the same at the same places, modulo the change in names: see server/request.c instead of main/http_request.c, etc. The algorithm and its bug are the very same.
Since I'm asked about a test case, try the following URL through a proxypass: http://cliki.tunes.org/CP%2FM http://cliki.tunes.org/Word%20Processors%3A%20Stupid%20and%20Inefficient For instance add this line to a test virtual host: ProxyPass /cto/ http://cliki.tunes.org/ And then access /cto/CP%2FM Log the result with ap_log_rerror as above...
This is not exactly the same problem, but it can be related. I've setup the following conf : ProxyPass /info/ http://internal:8888/info.asp? The problem is that "?" is replaced by a "%3F", like in this example : "http://website.com/info/param" --> "http://internal:8888/info.asp%3Fparam" If I replace the previous conf, with the following one, I get the correct request. RewriteRule ^/info/(.*) http://internal:8888/info.asp?$1 [P] "http://website.com/info/param" -> "http://internal:8888/info.asp?param" Is this a normal behaviour ?
Ok, the problem I had, is more similar to 13577 bugid. http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13577 Sorry for the Duplicate.
The mishandled escapes occur even with a regular proxy under Apache 1.3.31, not just with a ProxyPass proxy. In my httpd.conf I have <Directory proxy:*> Order deny,allow Deny from all Allow from .my.trusted.domain Allow from .other.trusted.domain </Directory> <VirtualHost *:15151> ProxyRequests On ProxyVia On NoCache * </VirtualHost> When I send a request to this proxy for http://myserver/something-with-%2B, the proxy asks myserver for /something-with-+, where the %2B was mistakenly decoded. This situation is like the one reported in #13577, but that one is marked as fixed and applies to Apache 2.0 only, and this bug (29554) mentions ProxyPass only. If the problem is more general, then it should be fixed more generally, not just for the ProxyPass situation.
I just noticed that Faré wrote: "Actually I believe canonicalization shouldn't happen in the STD_PROXY case either and the whole function should be scrapped." So please regard my previous comment as a "me too".
Changing bug summary to indicate bug is for proxy in general and for escapes in general, not just ProxyPass for / and :
Can someone please create a patch that makes the suggested change, removing the offending function, so it can be tested?
i use mod_proxy on apache 2.0.50 can somebody tell me when an official patch or bugfix or next apache release will be available? there have been no posts since 2004-Sep-18 thanks
Does anybody have a patch for either v2.0.x or trunk?
Have you tried this (much simpler) patch for the "misguided canonicalization" problem? http://issues.apache.org/bugzilla/show_bug.cgi?id=34688
Fixed for 2.0.55: http://svn.apache.org/viewcvs.cgi?rev=227435&view=rev
Heh. Now I screwed up the bug reference too. This bug is not fixed in 1.3 yet.
*** Bug 34688 has been marked as a duplicate of this bug. ***