• Another thread with this title seem to have been closed as resolved a few months ago — even though the solution provided is clearly not solving the problem correctly, and it seems like many wordpress users are having this problem: Files uploaded to e.g. the standard “uploads” directory cannot be properly password-protected. In the thread, https://www.ads-software.com/support/topic/password-protect-a-whole-directory, the solution given is to use a .htaccess file that checks for a wordpress login cookie, and redirects the users if no such is given.

    This, of course, gives you no real protection against users who know how to create their own cookies, or copy an old one, etc, making it only “security by obscurity” (google it). And it doesn’t allow you to differentiate between users with various permissions (as the role concept of wordpress otherwise gives you).

    I was surprised that no one thus seems to have provided a real solution, even though the php code involved should be rather simple. So, I wrote something up myself. Perhaps others will find it interesting as a starting point. The solution is to use a strict .htaccess file in the directory you want to protect, say “uploads/restricted”, i.e. containing just

    deny from all

    Then, add the file “getfile.php” below somewhere in you wp-contents hierarchy. This uses standard wordpress functions get_currentuserinfo which retrieves cookie information and validates it, and current_user->has_cap which tells you if the user has a given capability (these may be added and edited in wp-admin, editing the different roles).

    Finally, you add links to uploaded files from you restricted members pages as indicated below, by writing something like https://…/getfile.php?folder=xxx&file=yyy%5B&attach=yes%5D.

    Feel free to use and modify for your purposes.

    –Urban

    getfile.php:

    <?php
    
    //For retrieving files in protected dirs.
    //
    //Urban Engberg, 2011.
    //
    //Usage: getfile.php?folder=xxx&file=yyy[&attach=yes]
    //where folder is either "restricted" or "tools" -- or any other
    //restricted folder to be added here, file is a file in that directory,
    //and attach is an option to set disposition to attachment.
    
    //file should *not* contain "/"es to prevent hacking files by using
    //.. and the like.
    
    require('../../wp-blog-header.php');
    
    $folder=$_GET['folder'];
    $file=$_GET['file'];
    $fullpath='../uploads/'.$folder.'/'.$file;
    
    get_currentuserinfo();
    
    if (preg_match('/\//', $file) == 0 &&
        (($folder=='restricted' && $current_user->has_cap('restrict_content')) ||
         ($folder=='tools' && $current_user->has_cap('tool_content'))))
    {
       header("Content-Length: ".filesize($fullpath));
       header("Content-type: ".mime_content_type($fullpath));
       if ($_GET['attach']=='yes')
       {
         header("Content-disposition: attachment; filename=".$file);
       }
       header('Expires: 0');
       header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    
       ob_clean();
       flush();
    
       readfile($fullpath);
    }
    else
    {
      wp_redirect(<login page, or wherever you want to redirect>);
    }
    
    ?>
  • The topic ‘Password protect a whole directory’ is closed to new replies.