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
    Commented Oct 31, 2015 at 21:30

2 Answers 2

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.

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... Commented Oct 18, 2011 at 11:36
  • 2
    If the "auth" arrives in the cookie first (i.e. before "id") your rule won't work. Commented Nov 14, 2011 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
    Commented Nov 7, 2019 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
    Commented May 3, 2021 at 16:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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