• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 562
  • Last Modified:

Protect files from being download unless logged in

I have a page that can only be accessed by users who are logged in. On this page are links to pdf files. The problem I have is that while the page is secure the actual files are not. A user can type in the url to the file and download the PDFs without being logged in. One option I know is to protect the directory however this will prompt the user to enter another login. Another option I thought of is to place the files in a directory not viewable by the web such as where I may have

http/www/

and www is where the site lives. Can I place the files here:

http/downloads.

If that is the case I am not sure how I can access the files from http/downloads

Is there a better way to accomplish this?
0
SaltyDawg
Asked:
SaltyDawg
  • 10
  • 5
  • 2
  • +1
2 Solutions
 
gr8gonzoConsultantCommented:
Hi Salty,

For your situation, it's much better to place the files into a directory not viewable from the web. Since PHP usually has the ability to access any file on the server (as long as it has permission), you can have a PHP file that people go to when they want to view the PDF file. PHP then checks to see if they are logged in, and if they are not, it can send them to the login screen. Otherwise, the PHP can go and suck in the file data of the PDF and send it back to the user.

There's one simple function call to tell PHP to get all the file data and show it all to the browser:
<?
readfile("/the/system/path/to/the/file.pdf");
?>

So if your PHP script was http/www/pdfviewer.php and your PDF file was http/downloads/secret.pdf, then pdfviewer.php  might look like this:
<?
// Check to see if they are logged in
session_start();
if(.... logic here to check to see if they are logged in ...)
{
    // Show PDF
    readfile("../downloads/secret.pdf");
}
else
{
   // Redirect to login
   header("Location: LOGIN_URL_GOES_HERE");
}
?>

There are also special header parameters you can add later if you run into problems with browsers viewing the file, or if you want to prompt the user to download the file instead of viewing it inside their browser. The header() function is responsible for telling the browser how to handle the file data you're sending it with readfile().

If you DO need to use header() to tell the browser how to handle the data, you may want to look at the PHP documentation for that function. There are tons of examples that people have posted in the comments on how to show or download files.

http://us2.php.net/function.readfile
http://us2.php.net/manual/en/function.header.php
0
 
webwyzsystemsCommented:
I think you would be best to read up on, then implement HTACCESS.
This is a tried and true method to accomplish exactly what you are attempting. Since you are on Apache, everything is all ready to go.
Here's a pretty good link - read it and you should be able to complete what you want in an hour or less.
http://www.javascriptkit.com/howto/htaccess.shtml
0
 
SaltyDawgAuthor Commented:
using this method
readfile("../downloads/secret.pdf");

causes the browswer to open and read the file, displaying the binary data for the pdf..

How do I get the header file to work and prompt for download?

Also along with PDFs, Doc and XLS files may be there.
0
WEBINAR: 10 Easy Ways to Lose a Password

Join us on June 27th at 8 am PDT to learn about the methods that hackers use to lift real, working credentials from even the most security-savvy employees. We'll cover the importance of multi-factor authentication and how these solutions can better protect your business!

 
SaltyDawgAuthor Commented:
But doesn't HTACCESS prompt the user for a login
0
 
ycTINCommented:
* remember storage the files at secure area

<?php
	/*
		check the user access right here
		if the user is not allowed to access the file, redirect to other page
	*/
 
	//download file (file path, file name)
	downloadFile("test.pdf","test.pdf");
 
	public static function downloadFile($file,$filename){
		$b = get_browser(null, true);
		if ($b['browser'] === "IE") {
	 		$filename = urlencode($filename);		
		}		
		if(file_exists($file)) {
	        header('Content-Description: File Transfer');
	        header('Content-Type: application/octet-stream');
	        header('Content-Disposition: attachment; filename="'.$filename.'"');
	        header('Content-Transfer-Encoding: binary');
	        header('Expires: 0');
	        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	        header('Pragma: public');
	        header('Content-Length: ' . filesize($file));
	        @ flush();
	        readfile($file);
	        exit;
	    }
	}
?>

Open in new window

0
 
webwyzsystemsCommented:
htaccess will prompt for login if the user is not authenticated. If the user is authenticated - everything is good. I suppose it depends on how many users you are talking about, and how your system has to scale up. HTACCESS is suited for systems that will be growing beyond 10 users. Once implemented, you don't have the overhead of checking user access on every page. The authentication header is just passed along.

There is risk in all file download handling scripts in that they are usually passed a parameter to indicate what file is to be downloaded. You need to be very careful with your coding...or saavy folks will be downloading whatever they want from your server.

How are you currently authenticating users?
0
 
SaltyDawgAuthor Commented:
while HTACCESS does protect the files, it also prompts the user for authentication which is something I don't need. The user login before they can enter that section of the site, so I do not want to prompt them again for a different login. Don't want the customers to do anything that may be redundant.
0
 
SaltyDawgAuthor Commented:
ok I did the following below code and got this.

%PDF-1.4 %âãÏÓ 45 0 obj <> endobj xref 45 36 0000000016 00000 n 0000001461 00000 n 0000001541 00000 n 0000001670 00000 n 0000001910 00000 n 0000002330 00000 n 0000002551 00000 n 0000002836 00000 n 0000002912 00000 n 0000002986 00000 n 0000005105 00000 n 0000005705 00000 n 0000006111 00000 n 0000006774 00000 n 0000006808 00000 n 0000007088 00000 n 0000007371 00000 n 0000007882 00000 n 0000008099 00000 n 0000008400 00000 n 0000008482 00000 n 0000008888 00000 n 0000009284 00000 n 0000009566 00000 n 0000009850 00000 n 0000036009 00000 n 0000038678 00000 n 0000052912 00000 n 0000072194 00000 n 0000082650 00000 n 0000094979 00000 n 0000106173 00000 n 0000227454 00000 n 0000243142 00000 n 0000252789 00000 n 0000001016 00000 n trailer <<5A09A0F78B50814F80D5B79B0E6D008A>]>> startxref 0 %%EOF 80 0 obj<>stream xÚb```"VÆÈu B  cÊr¼`Ü 0ߢi O¡îrþG*`s®¿ÍýÀ¬ ÜÎ(<¾à²ÐmZ"ÉT¡P9ä.×é0Óf8´Jâ³eñÒu"ê:z#u; G`Hå¢+~!×bÛ¢ ú¬²"Ig.&x <: T³ì}H"ÅACÜ`£N²ªRÊ=Ì!Üï(Ô±Ù3P5¸Kl>£ Æ¥¥wtt¬]âa `¹4 @: ZRM\ÁZ & `¬¹ ýè~jTdà¿ê ¦4Àö)12è778po`¿Á°!¬C"Qa!Áoûæ'Ì»¶3´6ð0è5Æ-`?ÀüâR·ô¡3¬b! c}§ÕTù¨ö2Ô3D2H>àu`ã`}Ã80Ѳ üw{@! ÄÖ@¬ÃÀÿÆH3ñ-¬7yË endstream endobj 46 0 obj<> endobj 47 0 obj<> endobj 48 0 obj<>/ColorSpace<>/Font<>/ProcSet[/PDF/Text/ImageC]/ExtGState<>>> endobj 49 0 obj<> endobj 50 0 obj<> endobj 51 0 obj<> endobj 52 0 obj<> endobj 53 0 obj<> endobj 54 0 obj<>stream H0¬WÛrÛ6}çW /©3¢q¿ô-0ÝL:Ó4êô!éCÑ6[]lR²ë·|Q¿± QtI'ãH9ÝÅ9gwA5Ê8΍ÔHcÃ9-4Á¨©2R¡hý¶ý÷3$ E »ö®³³ï(ºn;_1*rCDç}HÄ¥Ì <ýUö6»ë·¥:çv[ØIp[! ®y}ugùÇàú[C’°Æ ë.Så K¥Âð+"S¥´aƱ\jR o1ÚGF@ó5Û]'F×)ÆÔçH0ÏîÇĨ{:û0ô"'´#|hÄI8¥TO0xgö)~ÖÍ'w29AÆÞ"ôÌnü{ÛEDãwI®5°0ºí¶äqR6ÍP°¦_aÔ’wÓ/hBy\S:vz^°Â1xt<¶Ù»­"Öý¥Ú:<Æ"LSà;pW¢~îá'WÐôô&©ìBÜnáàKd¾"îq²)AÔ(ì^sÄqÜËÐ*zmÖÇСÔä6}±Óe{ö¢"èÅ;D:Ëw/.û"²u+m¹õ"fûL¢_c±jkÊbeªüʷ¤þå~ÔZä(|èwR’ôØø"0°ßuÜSaÌûYQ7ó£9]­wsÂàËÚTE{hêí5j÷žÞm[tÛÌ0Î $Qðq_¯ªú8'çx ö7ÕüÏåÏÙÜ=[Sbè~õûÙÇC½^Y!~mÕ }ÿúξ޽K}§SP:fFõÝ°t\}H4â’a#ɮҷ¼&WpDÈé)&¢ßÆ:ցs, Þ ÉAĹ'¶c:Þî£g0Y¤×6½Í¸æx­UW*ùDìƱÉAõ ’~°I(R¹BW`°ÛÕ%(º1w]’!TCÂùàlÑGÉ3åß `!¦ý"r¿{Ü5Õ2.P½]ÕÐ:Å: ®`\Æj:x %}c5Ǭ/&P¥H0áõVÊ ¦Ñ§T7ï*¨®<® ÐǼ⩍gÆñPx¨/8Ý"¿·MÓ6à aæf®s=»­abhª󤡾®Kß²ÛÝÕ|AØî»6Û_@%âSæ ’^2Jr&A\û!Zí¿]QÂ8ÁÄ ÒÇ`o8|m ßÏ.þé÷+«uê ©ÄïÈ¥æ¹Á,õ9;´0$XC:¹"ÅcDT~Ǿ »C’~=xS<{ ¬¬ÛçmÕWè!a)L. ÇóÄÜA°

(...plus more)

it seems to open the file but doesn't know how to open it. Anyone know what I can do now?
	$filename = "../media/downloads/pdf/2006_BackDrop.pdf";
	header('Content-Description: File Transfer');
	header('Content-Type: application/pdf');
	header('Content-Disposition: attachment; filename="'.$filename.'"');
	header('Content-Transfer-Encoding: binary');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: public');
	@ flush();
	readfile($file);
	exit;

Open in new window

0
 
SaltyDawgAuthor Commented:

	$filename = "2006_BackDrop.pdf";
	$filename = "../media/downloads/pdf/2006_BackDrop.pdf";
	header('Content-Description: File Transfer');
	header('Content-Type: application/pdf');
	header('Content-Disposition: attachment; filename="'.$filename.'"');
	header('Content-Transfer-Encoding: binary');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: public');
	@ flush();
	readfile($file);
	exit;

Open in new window

0
 
SaltyDawgAuthor Commented:
miscopied again
	$filename = "2006_BackDrop.pdf";
	$file = "../media/downloads/pdf/2006_BackDrop.pdf";
	header('Content-Description: File Transfer');
	header('Content-Type: application/pdf');
	header('Content-Disposition: attachment; filename="'.$filename.'"');
	header('Content-Transfer-Encoding: binary');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: public');
	//@ flush();
	readfile($file);
	exit;

Open in new window

0
 
SaltyDawgAuthor Commented:
ok does anyone know any script to make downloads automatically pop up from a redirection like on download.cnet.com? Also can someone confirm that doing it this way will actually hide the directory the files are actually on?

Let me add the I am not trying to make it that secure. If a savvy individual is able to find the directory, its not a real problem. My goal is just to make it where a person cannot go directly to the file and by file the page links.

if I can do it this way I have already thought of a script to move the directory location periodically
0
 
ycTINCommented:
create file file.php for download


<iframe id="iFile" src="blank.html" style="display:none;"></iframe>
on user click the donwload link change the iframe url to file.php (e.g. file.php?id=123456)
0
 
ycTINCommented:
the code working fine with me, or you can try following header
and check you source code file do you have are invisible char before header()
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=$filename ");
header("Content-Transfer-Encoding: binary ");

Open in new window

0
 
SaltyDawgAuthor Commented:
we I use the header code I can open certain files expect application files. The browser opens the file within the browser screen and only shows the binary for that file. Like what I have shown above this is what I get when I use a pdf and the same with a .doc and .xls file.
0
 
ycTINCommented:
I created the demo for this function, and tested in FF/IE , linux/ Windows Server

Demo
http://demo.yctin.com/php-func-readfile/

Download Demo
http://demo.yctin.com/php-func-readfile/php-func-readfile.zip
0
 
SaltyDawgAuthor Commented:
Hello ycTIN
I think this is what I am looking for. Is this using the example you have above? How is it set up?

Thanks
0
 
ycTINCommented:
the code working in webserver default setting
you unzip the demo to your webserver still have same problem?
0
 
SaltyDawgAuthor Commented:
ycTIN & gr8gonzo
Ok I think I may have had some browser setting issues that cause problems with the download. I changed my setting and now your header functions are working. So I will continue to test this out and make sure I do have it right.

Thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 10
  • 5
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now