Steve Taylor photo

Detecting WordPress login via htaccess

I just had to come up with a quick bit of .htaccess code to very basically protect PDFs on a client’s site from being downloaded by people who aren’t logged into WordPress. I thought I’d share the code, specifically to highlight the way to detect if someone’s logged into WP through Apache’s directives.

Here’s my code:

RewriteCond %{SCRIPT_FILENAME} /wp-content/uploads/.*.pdf$ [NC]
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule .* http://domain.com/ [F,L]

The first line matches requests for PDF files in the uploads folder. You can change that however you want. The key is the second line, which is the match for the WP cookie you’ll have if you’re logged in.

Note that the name of the actual cookie has a string of random characters at the end, which I assume WP generates to make the login cookie hard or impossible to fake. I don’t know a way to access this value outside WP. I’d be interested if anyone knows how; I’d also suspect this would be a security hole in WP!

In the above example, if someone knew the PDF’s URL, didn’t have a login to your site, and really wanted to download the file, I’m sure they could fake the login cookie easy enough. If you need tighter security than this on downloads, you should probably look at a plugin like Download Monitor, which provides “mask” URLs for files, and thus can process login checks via PHP code from within the WP framework before returning the download.

Note also that I’m not sure that http://domain.com/ is necessary in the last line. The F flag after it returns a 403 status code, so you get the browser’s “Forbidden” page instead of any URL that you specify as the redirect.

Any suggestions for improvement to this quick-and-dirty trick welcome!

7 comments

  1. The random characters at the end of the cookie key are the md5 hash of whatever your site URL is. You can access that by doing this, in PHP:

    md5( get_site_option( ‘siteurl’ ) );

    Or access what WP calculates (a bit safer) by the constant, COOKIEHASH.

    And the whole string can be accessed via the constant, LOGGED_IN_COOKIE, which WP also defines.

  2. Thanks for the info Nathan – but I’m presuming there’s no way to access these values in .htaccess? That’s the nub of the above technique. Even if you can hardcode the site URL, does Apache provide an MD5 function in its directives?

  3. No, it doesn’t, as far as I can tell.

    However, a plugin for WP could be written to add this bit to .htaccess. If you did that, then passing PHP values to .htaccess would be no problem.

    I’m sure there’s a hook that fires after the rewrite rules get flushed, triggering WP to create/edit the .htaccess file. That would be the best point to insert the extra stuff.

    The insert_with_markers() function would be very helpful.

  4. OK… well I guess you could just hard-code that. But then it would be pretty easy to get past. OK, a bit harder than the above, but it’s still not really doing authentication or authorisation. I guess you could come up with something that actually modifies .htaccess dynamically with even more detailed login data every time someone logs in, but that could get hairy. Keep me posted if you come up with anything more elegant!

  5. Hi there, nice one! Actually, I would like to make a redirect to https, only if the user is *not* logged in. So I should check for the cookie not being set. Do you also have a one-liner for that? :)
    …after so many years, one more comment! :)

  6. Steve Taylor avatar Steve Taylor

    Can’t say I’ve got anything to add here that I wouldn’t be Googling just like you for :)

Comments are closed.