1

I've in the past protected PDFS when a user is not logged in using the following code :

RewriteCond %{REQUEST_FILENAME} ^.*(pdf)$
 RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
 RewriteRule . - [R=403,L]

For some reason it quit working on me. Research has shown that maybe wordpress-logged_in is no longer relevant as it was a hacking hole. Is there an alternative solution for protecting PDF documents if a user is not logged in?

These pdfs are not embedded on a page rather "hot linked" if you will. I'm not looking for a bloated plugin. Just a solution to protect PDF's specifically.

Edit:

Below is my full htaccess.

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /new/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /new/index.php [L]
</IfModule>

# END WordPress


RewriteCond %{REQUEST_FILENAME} ^.*(pdf)$
RewriteRule ^(.*)$ /wp-content/download-protect.php?file=$1 [L]

# disable directory browsing in WordPress
 Options -Indexes

# protect wp-config.php
 <files wp-config.php>
order allow,deny
deny from all
</files>

#  Protect .htaccess
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>
hfw
  • 83
  • 1
  • 12

4 Answers4

5

This is a slightly heavier solution than yours, but IMHO it is still better than some 'Super Protect Your PDFs' Wordpress plugin

All you have to do is place download.php file somewhere in your WP installation (for example wp-content folder). Then you have to redirect all the requests to PDF files will be passed to download.php script. It includes some basic WP stuff so you can use WP functions, such as is_user_logged_in()

.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} ^.*(pdf)$
RewriteRule ^(.*)$ /wp-content/download.php?file=$1 [L]

download.php

require_once('/path/to/wp-config.php');
require_once('/path/to/wp-includes/wp-db.php');
require_once('/path/to/wp-includes/pluggable.php');

if (!is_user_logged_in()) {
    // redirect to login page or show the message + login form
    die; // or exit, wp_redirect etc
}

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));   
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp); 
Salaros
  • 1,444
  • 1
  • 14
  • 34
  • This is an interesting idea. I'm not getting any read from .htaccess. I'm not hitting any redirect t o the download file. – hfw Feb 22 '16 at 17:37
  • I've included my full htaccess above. – hfw Feb 22 '16 at 17:43
  • @hfw could you give me an example of an "unprotected" PDF URL Is it just a `http://example.org/wp-content/uploads/2016/02/xxxx.pdf`-like URL or not? – Salaros Feb 24 '16 at 13:45
0

I've implemented a similar solution to what @salaros has suggested but utilized WordPress action parse_query.

RewriteRule wp-content/uploads(\/[A-Za-z0-9_@.\/&+-]+)+\.([A-Za-z0-9_@.\/&+-]+)$ index.php?pre_dir_acc_61co625547=$1&is_direct_access=true&file_type=$2 [QSA,L]

So basically any PDF files with the above format (the default file format on WordPress) will be then redirected to our plugin where we'll check whether the file is protected or not (done through WordPress admin).

If it is, we redirect them to 404 page. If it's not, we return the original files.

There is also a so-called "Private URL" generated by our plugin for you to access the file after its original URL is blocked.

For more information, please check out our Prevent Direct Access plugin.

Rexy Hoang
  • 886
  • 7
  • 7
0

You can block PDF's downloads for not logged in users (wordpress) just using htaccess

This is my code to block pdf,docx,doc,zip. What seems dificult to block are images because the browser needs to download theme to show them on your screen...

Thats my code to redirect to home page if a not logged in user tryies to download a file:

<IfModule mod_rewrite.c>
RewriteEngine on
ErrorDocument 403 https://www.yourSITE.com/
RewriteCond %{REQUEST_FILENAME} (.*)
RewriteCond %{HTTP_COOKIE} !wordpress_logged_in_([a-zA-Z0-9_]*) [NC]
RewriteRule \.(zip|doc|docx|pdf)$ – [NC,F,L]
</IfModule>
gtamborero
  • 2,898
  • 27
  • 28
0

To prevent and will not omit code in .htaccess file add below code in function.php file

add_filter('mod_rewrite_rules','output_htaccess');
function output_htaccess( $rules ){
$nrule = 'RewriteCond %{REQUEST_FILENAME} ^.*(pdf)$
RewriteRule ^(.*)$ /wp-content/themes/theme-name/download.php?file=$1 [L]';
$rules = str_replace('RewriteBase /', $nrule , $rules);
return $rules;
}

create download.php file inside theme folder

require_once($_SERVER['DOCUMENT_ROOT']. '/wp-load.php');

if (!is_user_logged_in()) {
        // redirect to login page or show the message + login form
        die('Please login'); // or exit, wp_redirect etc
}

$filename = $_GET["file"];
$filePath = $_SERVER['DOCUMENT_ROOT']. "/".$filename;
header('Content-type:application/pdf');
header('Content-disposition: inline; filename="'.$filename.'"');
header('content-Transfer-Encoding:binary');
header('Accept-Ranges:bytes');
@ readfile($filePath);