I found this sulotion perfect for protecting the media files on Wordpress. I ran a membership Wordpress website. I tried this solution, but the thing is, the videos on my website's pages are not playing anymore. I embedded some premium .SWF files on my pages, and wanted to protect those .SWF files from direct URL access.

Hi @enes9, this requires additional debugging. I assume this is related to headers being send in the request or the response. Also ensure that the flash plugin of your browser sends the needed cookies. You should be able to gather more information by tracking the network connections with Firebug in Firefox or a similar tool in the browser of your choice.

Sorry for noob question, but how would this be modified to work on WP Multisite for all the subsites? So the user would have be a subscriber of the site (rather than the network preferably) to access the files.

Hi! Thanks for this. I'm a total noob and stumbled upon this. How would I change the .php file and .htaccess for the folder named, "work-files" which at the same level as "wp-content" (ie it's in the root folder). Also, can it work recursively through all the subfolders? Thanks!

Hi! Thanks for this script! I have a basic (and silly) question, but which ist the better folder to place the script? I have placed it inside wp-content/uploads and I'm getting a 404 error (accessing a file directly from URL), as the file is seen as a post.

Another question: I want it just to check the uploads when accessing them by URL, but not the images attached to a post. How could I parse it? Thanks in advance!

I am trying to use your script on a subfolder inside uploads. at the moment it is '/wp-content/uploads/private/'.
The redirect script is working super well, but when I put the credentials it leads to a '404 - file not found.'

I have add 'private' in the code below, now it open the files, but you can access the file without be logged in.
$file = rtrim($basedir,'/').'/private/'.str_replace('..', '', isset($_GET[ 'file' ])?$_GET[ 'file' ]:'');

Ok guys,
apparently to achieve what I need, we have to change the 'structure' of the wordpress, so I gave up on it for time consuming issue and decided to create a folder called public and do the other way around, now I am facing another problem.
My images sitting on the uploads folder will not show if I am not logged in. How can I solve that?

@Braus: I see no technical limitation with the private folder you aimed for first, just ensure all paths are correct and you shouldn't have any issues. Albeit I didn't test it, so let me know if you require additional support.

@beezwings: This should be merely a configuration setting, also as the traversal is by the file-system and supported from your OS, I don't see any recursion issues here. With a little modification of the Worpdress upload path configuration, I see no technical showstoppers to just do what you want to do.

This includes the fix for Wordpress 3.6.1 mentioned above (thanks sgissinger!) as well as checks the true filesystem path of the file using realpath() in order to prevents directory traversal attacks. The unmodified script has a simpler version of this in place, but handles it via string replacement - realpath() ensures that any symbolic links and references are resolved first.

After a lot of painful hours I found out that the WP include (require_once('wp-load.php');) is adding a linefeed in the output. As a result binary files are seen as "corrupted", e.g. my png files starts with a linefeed.

I tried to use the PHP OB functions to trap this extra linefeed but it is not working, i.e. the linefeed is still there.

Anyone faced the same challenge in the past? Anyone with a potential solution?

If you're a PHP/.htaccess noob like me, and you're trying to implement this, please read before attempting to implement. It may save you some head banging and throat punching...

dl-file.php file goes in your public_html directory (the same place as your wp-config.php files and such)

Add the additional lines posted by stewartadam for new version of WordPress in dl-file.php

The .htaccess file you should be modifying is the one in the above directory.

This solution locks EVERYTHING in your wp-content/uploads directory. This was the issue I was facing and was having misunderstandings with.

I'd imagine most people don't want their entire wp-content/uploads directory to be locked. Header images, images in public posts, etc. are all stored in this wp-content/uploads directory by default. If you're wanting to have a dedicated "membersonly" folder inside your wp-content/uploads directory, leaving alone existing content that you don't want to restrict, you'll have to make some modifications to your .htaccess file.

The location is important here. It must come before the two lines of RewriteCond and one line of RewriteRule. These three lines send all file requests to index.php, which is not what we want. Putting THIS DL-FILE.PHP ADDITION before those three lines ensures dl-file.php is getting called when it should be.

In the RewriteRule ^wp-content/uploads/(membersonly/.*)$ line, it's important if you want a specific directory to be protected that you encapsulate it in parenthesis like that. What is in parenthesis gets sent to dl-file.php. This basically says, any calls to anything inside membersonly get sent to dl-file.php, with the 'file' variable being set to membersonly/SomeFile.

Hopefully this helps at least one person save a few unnecessary hours of anger and frustration...

I was wondering if anyone has tried this with a multisite installation since ms-files was removed. Previously, it was apparently sufficient to change ms-files.php so it wouldn't use SHORINIT and add the check. I wonder how to add the dl-file.php back to to rewrite rules given how the structure of the blog/files has changed since WP 3.5. Any pointers? Thanks!

I want to use this code to block access to a directory outside of my WordPress install. How do I modify the PHP file code to make it load the URL (not an image file like the code was written for)? When I use the dl-file.php code as-is, the URL loads as 404 I'm just not skilled in writing PHP to know how to modify it to say 'load URL'. Any thoughts?

Seems like this thread is pretty old, but still chugging along. I was able to get this to mostly work using the dl-file.php text that scot90 posted. The issue I have, however, is that upon accessing a file from the protected folder, I'm logged out of the Wordpress site. So I get the file, but then I have to log back in again. Has anyone else seen this?

Edited 1 time

Dec 5, 2016

This doesnt seem to be working? if i sure to mysite.com/wp-content/uploads/private i'm re directed to the login... if i surf to a file within private im am able to access it and i'm not directed to login?

how would this be modified to perform the same actions but within a folder outside the uploads folder. such as within a plugin folder? could I just replace the wp_upload_dir calls to wp_plugin_dir and my file path? thanks for the insight