Issue with protecting files from download

Ask about general coding issues or problems here.

Moderators: egami, macek, gesf

Post Reply
speckytwat
New php-forum User
New php-forum User
Posts: 14
Joined: Tue Sep 05, 2017 12:33 am

Fri Oct 06, 2017 7:12 am

I have a problem with a folder in a site, where I have a simple PHP login system and a landing page where a user can download their personal file (a PDF) via a download link.

I want to stop people from being able to browse directly to the PDF via web browser without logging in. It seems that this is far more difficult than I had hoped. I've tried adding the following to an .htaccess in the folder:

IndexIgnore *

and also

Options -Indexes

Neither of which even stopped the folder showing its file contents in a web browser.

What I need is for the user to be able to access their personal file for download when they log in, but NO ONE should be able to use a web browser to do it.

I've seen suggestions along the lines of placing the folder for the PDFs outside of the www root, which sounds great, so I made the upload script (used by the site admin) try to do this: (partial code below)

Code: Select all

		$target_dir = "../../reports/";
		$target_file = $target_dir . basename($_FILES["_Report"]["name"]);
		if (move_uploaded_file($_FILES["_Report"]["tmp_name"], $target_file)) {
        	echo "The new report ". basename( $_FILES["_Report"]["name"]). " for ".$username." has been uploaded.";
    }
This *appears* to work because the success message is outputted. The files appear in the "reports" folder. However when I log in as the user and click the link, it's generated https://domainname/reports/filename i.e as if the "reports" folder is inside www! And the browser gives a "file not found" error for obvioius reasons.

Anyone got any ideas about how to do this? For such a simple requirement there must be a way to allow access only to logged-in users and prevent any web browser based access.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 525
Joined: Mon Feb 22, 2016 5:52 pm

Fri Oct 06, 2017 8:13 am

You can create a php page which sends the file to the browser, that way, the user will only be offered the link to the file if they are logged in. Have a read of this, it may be the answer or will at least show you how it can be done.

speckytwat
New php-forum User
New php-forum User
Posts: 14
Joined: Tue Sep 05, 2017 12:33 am

Fri Oct 06, 2017 8:23 am

Thanks, I tried using that but what happened was that it outputted lots of strange characters over the screen e.g diamonds with question marks inside them etc...

How would I use that code inside what I already have though? i.e how would I integrate it with the file display in the user's download page:

this is what I currently have:

Code: Select all

	$username = $_SESSION['username'];
	$getreport = $conn->query("SELECT * FROM reports WHERE UserName LIKE '$username'");
	
	if ($getreport->num_rows == 0) { echo '<p>Sorry, your report is not ready yet. We will notify you when it is ready to download.</p>'; }
	
	while ($row = $getreport->fetch_assoc()) {  
  			$downloadfile = $row["FileName"];

			echo '<p><a href="../../reports/'.$downloadfile.'">Your report is ready- click here to download.</a></p>';

		$count++ ;
		}


Post Reply