0

To give context, the goal:

Using apache httpd I need to test a contextual segment of the request uri is contained within a cookie value sent in the header before redirect the user to a splash page for cookie confirmation, or allowing them access to the site.

Given the following:

url: http://www.example.com/en/gb/main.html

cookie: ;acceptedCookies=fr,en,de,it

If the language segment of the url = "en", and this is amongst the users acceptedCookies. Then allow the user access to the main site, else redirect the user to the splash page.

What I've tried:

SetEnvIf Host ^ uriCountryCode=NUL
SetEnvIfNoCase Request_URI "^(.+)?\/([a-zA-Z]{2})\/[a-zA-Z]{2}\/.+$" uriCountryCode=$2

SetEnvIf Host ^ acceptedCookieList=EMP 
SetEnvIf Cookie "(^|;\*)acceptedCookies=([^;]+)?" acceptedCookieList=$2
#1st.
<If "%{acceptedCookieList} =~ %{uriCountryCode}">
// Doesn't work
</If>

#2nd.
<If "env('acceptedCookieList') =~ env('uriCountryCode')">
// No luck
</If>

#3rd.
<If "env('acceptedCookieList') =~ /env('uriCountryCode')/">
// Now I'm just guessing
</If>

#4th.
RewriteCond %{acceptedCookieList} !%{uriCountryCode}
RewriteCond %{REQUEST_URI} !^/en/gb/splash.html$ [NC]
RewriteRule ^(.+)$ /mt/en/splash [L,R=301]

I've recently learnt that some of these modules i.e env('x') won't load SetEnvIf variables dues to the SetEnvIf variables not loading early enough to be accessible but i'm trying to find a httpd solution to this my problem

  • Thanks @Avi - Too many nights focusing on this problem has me being stupid, can't believe I never saw the flaw sooner. I'll scrap the solution and start again. – CoDemystified JavaFx Feb 25 '19 at 21:49

2 Answers2

1
  1. mod_rewrite can set environment variables.
  2. Use a 302 redirect (Moved Temporarily) instead of a 301 redirect (Moved Permanently).
  3. Matching against an arbitrary regex provided by the client (i.e. the contents of the acceptedCookies cookie) is dangerous. Nevertheless, the httpd expressions language doesn't have a built-in "contains" function and so it's non-obvious how to avoid the regex matching. This will make your server(s) susceptible to DoS attacks.

All that said, consider something like:

RewriteCond %{HTTP_COOKIE} acceptedCookies=([^;]+)
RewriteRule ^.*$ - [E=COOKIE_ACCEPTED_LANGS:%1]

RewriteCond %{REQUEST_URI} ^/([^/]+)/.*$
RewriteRule ^.*$ - [E=URL_LANG:%1]

RewriteCond expr %{ENV:URL_LANG} =~ %{ENV:COOKIE_ACCEPTED_LANGS}
RewriteCond %{REQUEST_URI} !^/en/gb/splash.html$ [NC]
RewriteRule ^.*$ /mt/en/splash [R]
Avi
  • 1,231
  • 10
  • 23
0

Following @Avi solution will work, but any solution allowing client-side values unknown in length to perform validation is fundamentally flawed, posing the potential risk of exceeding buffers and DOS.