9

I have a site that uses PHP session for authentication. There is one directory that I would like to restrict access to that does not use any PHP, it's just full of static content.

I just don't know how to restrict access without every request going through a PHP script. Is there some way to have Apache check the session credentials and restrict access like Basic Auth?

6

Unless you've changed the settings, PHP session data is stored in a variation on its own serialize() format in a temporary directory, and it's not easy to get at that without using PHP itself.

unfortuantly, you appear to want the speed of static served files while dynamically authorising each request, which are not really compatible goals. You might comprimise by having a super-light PHP script which you then use mod_rewrite to rewrite requests to files within it to, which passes though things that are fine. Super simple example:

.htaccess:

 RewriteEngine On
 RewriteMap auth prg:auth.php
 RewriteRule (.*) ${auth:$1}

auth.php:

#!/usr/bin/php
 <?PHP
 set_time_limit(0); # This program needs to run forever. 
 $stdin = fopen("php://stdin","r"); # Keeps reading from standard in
 while (true) {
        $line = trim(fgets($stdin));
        if (isset($_SESSION['USER_LOGGED_IN'])) {
                echo $line\n";
        } else {
                echo "authfailed.html\n";
        }
 }

notably, that PHP script is running forever, so you'll need to restart apache if you change it, I think.

This is all untested, but that's roughly the direction I think you'd have to go in.

References:

3
  • I like this approach, but I am wondering if a RewriteMap script has access to anything other than stdin? Does it have the context of cookies etc?
    – Cogsy
    Mar 25 '10 at 6:27
  • Actually, yes, you do have a point. You can send in the value of cookies using mod_rewrite's environement variables syntax (So I think the syntax would become something like ${auth:$1 $COOKIES} and you'd have to split the line of stdin by arguments, by this method you could pick up the session contents.
    – Aquarion
    Mar 25 '10 at 16:04
  • What if you set a cookie by login with a constant auth id (lots of bit length), and you check it by directory access? Not the best solution, but it can work on admin pages... (By file share pages it doesn't work because users can share the cookie...)
    – inf3rno
    Feb 16 '12 at 3:20
1

If you had a particular cookie you can expect, then you can test for its absence with mod_rewrite and give a 403 Forbidden.

RewriteCond %{HTTP_COOKIE} !LoggedIn=true
RewriteRule .* - [F,L]

But, if anyone knew that they needed a cookie set with "LoggedIn=true", then they could easily get around your "protection".

A PHP session is specific to PHP. Apache has no way of using any info in a PHP session. You would have to have some authentication module specifically for doing the session verification.

What I've seen most people do is have a PHP script handle the serving of the static content in that it gets the request, verifies the session, reads in the file and sends the content out with the appropriate MIME info.

1
  • Or you can modify the .htaccess file by every login, logout and gc...
    – inf3rno
    Feb 16 '12 at 3:24
1

The conventional solution for that problem is to redirect every call on that folder to a php file, which checks the user permissions, and after that it reads the file, and send it to the output stream or redirects the user to the "no permission" site. For example...

Another tricky way to protect you files is to generate a token from the session_id, and a static salt (and optianally from the static file path), and check it by the file accessing. So you have to regenerate that token in you htaccess file. I don't know whether it's possible only with .htaccess, or you have to use php for that. I found a similar solution here. I'm 99% convinced, that the md5 is not a built in mod rewrite feature.

1
  • 1
    I love the idea from the Blogspot link to use RewriteMap to a prg://… shell script resource which does all the actual MD5 encryption and verification. I need to test this and make sure it works on my setup, but it looks like it should work with vanilla Apache + the mod_rewrite module.
    – thirdender
    Aug 31 '15 at 12:43
1

My plan to solve this problem is now to

  1. Redirect the request to PHP

    RewriteEngine on
    RewriteRule ([0-9a-z-_]+)$ authenticateUser.php?&file=$1 [L]
    
  2. Authenticate the user in PHP (all other authentication methods are maybe too weak or require writing into files all the time)

    if ( User::hasPermission() && isSane( $filePath ) ) {
        // 
        header( 'X-Sendfile: ' . $filePath );
    }
    
  3. Use Apache's mod_xsendfile (docs, github)

0

Yes to Basic Auth if you're using mod_php. http://php.net/manual/en/features.http-auth.php

1
  • Authentication is already using PHP Sessions. I'm really looking for a way to use the session cookie.
    – Cogsy
    Mar 24 '10 at 3:13

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.