1

I have the following mod_rewrite rule, which works fine in my Apache 2.x on CentOS 6 Linux machine, but it is not complete:

RewriteCond %{HTTP_COOKIE} !id
RewriteCond %{REQUEST_URI} ^/sites/default/files/pictures/picture-
RewriteRule .* /images/dummy.png [L]

because I'm trying to change it in 2 ways:

  1. Actually 2 cookies (and not just 1 as above) should be present: id and auth (but I don't know, how to do (X or Y) and Z with mod_rewrite)

  2. I'd like to verify that the value of the auth cookie is a 32 hex chars string (an MD5 hash) and that the value of id cookie is numeric.

The background is that I've gotten a bill for EUR 1000,- from Getty Images, because one of the Drupal users on my server has supposedly used their picture as an avatar. I'm not looking for any lawyer or pseudo-lawyer advice here, just for the way to display a dummy image instead of real user pictures to web crawlers.

And yes, I've noticed in the mod_rewrite doc, that I could pass the cookie values to an external script through mod_rewrite (for verifying the MD5 hash), but I'd like to tackle this later.

UPDATE 2:

I've come up with the following

RewriteCond %{REQUEST_URI} ^/sites/default/files/pictures/picture-
RewriteCond %{HTTP_COOKIE} !auth=[a-fA-F0-9]{32} [OR]
RewriteCond %{HTTP_COOKIE} !id=[0-9]+
RewriteRule .* /images/dummy.png [L]

but I'm not sure, if the above RewriteCond's act as X and (Y or Z) or (X and Y) or Z

1
  • 1
    Instead of specifying RewriteCond %{REQUEST_URI} ... it is more efficient to specify this URL pattern in the RewriteRule pattern. The RewriteRule is processed first.
    – MrWhite
    Oct 31 '15 at 21:30
2

How about this:

RewriteEngine On
RewriteCond %{HTTP_COOKIE} !(^|;\s*)id=[0-9]+(;\s*)auth=[0-9a-fA-F]{32}(;\s*)
RewriteCond %{REQUEST_URI} ^/sites/default/files/pictures/picture-
RewriteRule .* /images/dummy.png [L]
4
  • Does this cover if "auth=" is in front of "id="? And is maybe \b better here, than (^|;) ? But I get your idea, thanks... Oct 18 '11 at 11:36
  • 2
    If the "auth" arrives in the cookie first (i.e. before "id") your rule won't work. Nov 14 '11 at 15:42
  • A workaround (if you control the setting of the cookie) is to combine the values into one cookie foo=id:auth; and then parse out id and auth.
    – Marc
    Nov 7 '19 at 5:38
  • 1
    @AlexanderFarber "is maybe \b better here, than (^|;\s*)" - Generally, no. If, for example, you had another cookie of the form something-id then this will erroneously satisfy your test when the required id cookie is not present.
    – MrWhite
    May 3 at 16:37
3

but I'm not sure, if the above RewriteCond's act as X and (Y or Z) or (X and Y) or Z

In the directives you posted it is the former: X and (Y or Z)

However, as mentioned in my comment above, it is more efficient to do the URL-path check in the RewriteRule pattern - since this is what's processed first. This avoids the RewriteRule being processed for every request (as is what happens when using a catch-all pattern like .*). You then have just two ORd conditions that check the absence of either cookie (in any order). For example:

RewriteEngine On
RewriteCond %{HTTP_COOKIE} !(^|;\s*)id=[0-9]+ [OR]
RewriteCond %{HTTP_COOKIE} !(^|;\s*)auth=[0-9a-f]{32}
RewriteRule ^/?sites/default/files/pictures/picture- /images/dummy.png [L]

The (^|;\s*) pattern prefix before the cookie name is just to safeguard against the situation when you have other cookies with a similar (but longer) name. eg. uid or userauth, etc. If that is not possible then this subpattern could be omitted.

[0-9a-fA-F]{32} - The result of an md5 hash is usually always lowercase, it's certainly never mixed case, so checking for a-f and A-F is unnecessary.

There is no need to check for (;\s*) at the end of the cookie value, as in @quanta's answer, since this is not part of the value you are trying to validate. And the Cookie: header is not expected to end with a ; anyway - so this may not even match.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.