Need to allow encoded slashes on Apache
Solution 1
This issue is not related to Apache Bug 35256. Rather, it is related to Bug 46830. The AllowEncodedSlashes
setting is not inherited by virtual hosts, and virtual hosts are used in many default Apache configurations, such as the one in Ubuntu. The workaround is to add the AllowEncodedSlashes
setting inside a <VirtualHost>
container (/etc/apache2/sites-available/default
in Ubuntu).
Bug 35256: %2F
will be decoded in PATH_INFO (Documentation to AllowEncodedSlashes
says no decoding will be done)
Bug 46830: If AllowEncodedSlashes On
is set in the global context, it is not inherited by virtual hosts. You must explicitly set AllowEncodedSlashes On
in every <VirtalHost>
container.
The documentation for how the different configuration sections are merged says:
Sections inside
<VirtualHost>
sections are applied after the corresponding sections outside the virtual host definition. This allows virtual hosts to override the main server configuration.
Solution 2
I kept coming across this post for another issue. Let me just explain real quick.
I had the same style URL and was also trying to proxy it.
Example: Proxy requests from /example/
to another server.
/example/http:%2F%2Fwww.someurl.com/
Issue 1: Apache believes that's an invalid url
Solution: AllowEncodedSlashes On
in httpd.conf
Issue 2: Apache decodes the encoded slashes
Solution: AllowEncodedSlashes NoDecode
in httpd.conf (Requires Apache 2.3.12+)
Issue 3: mod_proxy attempts to re-encode (double encode) the URL changing %2F
to %252F
(eg. /example/http:%252F%252Fwww.someurl.com/
)
Solution: In httpd.conf
use the ProxyPass
keyword nocanon
to pass the raw URL thru the proxy.
ProxyPass http://anotherserver:8080/example/ nocanon
httpd.conf file:
AllowEncodedSlashes NoDecode
<Location /example/>
ProxyPass http://anotherserver:8080/example/ nocanon
</Location>
Reference:
- http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
- http://www.silverdisc.co.uk/blog/2009/02/28/url-canonicalisation-and-normalisation
- Cannot match %2F in mod_rewrite
Solution 3
I wasted a great many hours on this problem too. I'm a bit late to the party, but it seems there's a solution now.
As per this thread, there is (was) a bug in Apache such that if you have AllowEncodedSlashes On
, it prevents the 404, but it mistakenly decodes the slashes, which is incorrect according to the RFC.
This comment offers a solution, namely to use:
AllowEncodedSlashes NoDecode
Solution 4
Replace %2F
with %252F
at the client side.
This is the double-encoded form of the forward slash.
So when it reaches the server and gets prematurely decoded it will decode it to %2F which is exactly what you want.
Solution 5
in light of all the hassles, i opted for base64_encoding followed by urlencoding. It works without having to fool around with apache server settings or looking at bug reports. It also works without having to put the url in the query section.
$enc_url = urlencode(base64_encode($uri_string));
and to get it back
$url = base64_decode(urldecode($enc_url));
http://example.com/admin/supplier_show/8/YWRtaW4vc3VwcGxpZXJz
http://example.com/admin/supplier_show/93/YWRtaW4vc3VwcGxpZXJzLzEwMA%3D%3D
Related videos on Youtube
tommizzle
Updated on July 05, 2022Comments
-
tommizzle almost 2 years
I'm currently trying to place a URL within a URL. For example:
http://example.com/url/http%3A%2F%2Fwww.url2.com
I'm aware that I have to encode the URL, which I have done, but now I am getting a
404
error back from the server rather than my app. I think my problem lies with apache and can be fixed with theAllowEncodedSlashes On
directive.I've tried putting the directive at the bottom of the httpd.conf to no effect, and am unsure what to do next. Am I putting it in the right place? If so, does anyone have any other solutions?
-
Woland over 5 yearsIn addition to stackoverflow.com/a/9933890/6333217 : If you use
RewriteRule
instead ofProxyPass
you should addNE
flag to avoid decoding.
-
-
tommizzle over 13 yearsHi Rob. Yeah, I got the same result, so had to implement the architecture change too. Little disappointing, but just glad that it works at this stage. Thanks.
-
Chris about 10 yearsI don't like it, but ended up going this way too
-
Daniel Beardsley almost 10 yearsThe first two issues were pretty well documented around the net, but issue 3 was a tough nut to crack till I saw this answer. THANK YOU.
-
Jose De Gouveia almost 10 yearsthis solution worked like a charm! this should be the Answer! thank!
-
Thomas Vander Stichele over 9 yearsWow. Perfect answer, works, concise. Please make this the accepted answer.
-
Terje Bråten about 9 yearsYou will get the same problem here, because '/' is a base64 character.
-
William Isted almost 8 yearsA urlencoded
/
regardless of the method to make it is still a%2F
is it not? -
leeb almost 8 yearsThe top comment on the php.net website for base64_encode() has a good solution for a URL-safe version: php.net/manual/en/function.base64-encode.php#103849 Basically it involves replacing + and / with alternative chars on encode/decode.
-
cmroanirgo over 7 yearsIt took me ages to find this answer. Sometimes one upvote is simply not enough. Many thanks!
-
Ameo about 7 yearsThanks so much for this; the exact thing that was needed.
-
koppor almost 7 yearsYou should never every double encode: tools.ietf.org/html/rfc3986#section-2.4
-
Neal Gokli almost 7 years@koppor But you can double-decode it if you know it has been double-encoded. So you could double-encode that entire component, and then do a second decode on that component on the other side?
-
Andrew about 5 yearsworks a charm when using ProxyPass. Fixed an issue with magento API when using SKU codes containing a slash.
-
NullIsNot0 over 4 yearsIf you are using balancer, you should add
nocanon
toProxyPass
directive notBalancerMember
. Example:ProxyPass /webservice balancer://api/webservice nocanon
Thanks to @stenix stackoverflow.com/a/14339060/8433375 -
Fernando Crespo about 4 yearsMy problem was a little different, but
nocanon
resolved it. I have a GiLab omnibus installation behind a Apache proxy with SSL and some urls (the ones with slashes) failed to go through. Usingcanon
fixed it! So glad I came across this.