I need a method to protect the download URL of a file from being seen by the downloader.
The idea is that the user is given a download link after paying, but to stop them spreading the URL among their friends who haven't paid.
What are some common solutions to this? Possibly changing file name?
(I can do PHP, and mySql this post is for methods really)
If users have an account on your site, stock in your DB if they paid the download. Then give them a link such as download.php where you verify if they paid, and if yes, do a location to the file. Example for a .pdf :
if($userpaid === true) {
$filename = 'congrat-you-paid-it.pdf'; //Name to display
$file = './download/pdf/secretlink.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="'.$filename.'"');
header('Content-Length: ' . filesize($file));
#readfile($file);
exit;
}
One solution could be to use SESSION or a similar temporary storage and generate download URLs at run-time. So clicking on the URL again may not work.
Also, direct access to the files should not be allowed.
Create a token. Store at your end and send with file URL as well. When user clicks the URL match the token and allow the download, then remove token from your storage.
You've to generate new token every time registered user wants to download though.
Use sessions is quick and easy, for better security, what you can do is:
Put the actual file in a separate folder and put a .htaccess in it to
only allow the script to access that file.
Then generate a random unique variable
Then make a temp file with that name and give the link to it to the
client
Finally run a cron job to delete the unnecessary created files.
Related
This seems like it should be simple. I have a set of files I have to store outside of the webroot and have an access script to call them. I also need to sometimes tell a PDF that must be called via this proxy script to open at a specific page. Releveant part of the script below:
header('Content-type: application/pdf');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="'.$file_name.'"');
readfile($file);
$file_name is just the basename() of the file, and $file is the path to the file, with #page=2, or #page=10, or whatever appended to it. If I remove the hashtag portion, the script works fine and the PDF opens with no errors. When the hashtag portion is there, all the programs tell me the PDF has been corrupted and can't be open.
I can't seem to find anything on here or Google as to what I need to do. Do I need to set an additional header to simulate the hash tag? Use exec() to call some command line code instead of using readfile()?
Any insight would be greatly appreciated.
You have to append the #page=2 (or whatever page you want to open) to the URL in the browser, not the filename in the proxy-script.
You currently try to open a file myFile.pdf#page=2 from the filesystem that does not exist as the filename is myFile.pdf
The feature to open a pdf-file on a specific page on the other hand is implemented in the browser or it's PDF-plugin. Therefore the information which page to open has to be given to the browser via the URL. So you should call your proxyscript like this: http://example.com/proxy.php?myFile.php#page=2
Update:
If you want to download the file and open it at a specific page every time the file is opened from the local file-system of the user, you will have to edit (or recreate) the PDF-File.
i am using PHP to connect to a MySQL Database and customers can login to my website and it lists rows form a table based on their login etc.
I need to be able to display a link to a file name in the database but i don't want users to be able to see the link to the file.
for example, they can download file 1234.pdf and if they can view the actual link, they might think of going to the same location but doing file 5678.pdf which is only meant for another user to download.
so basically i want to hide the link in a long string or something but i'm not sure where to start - any ideas?
Thanks
EDIT:
lets say Customer A logs in, they can view rows from table1
TABLE1
customer file_link
A 1234.pdf
A 5678.pdf
B 8765.pdf
B 4321.pdf
so, i dont want customer A to be able to view the links for customer B.
i mean, if customer A hovers over a link and can see the main file path they can type this in their web browser and then change the file name (guess it) to something else and download another customers file(s)
if you're planning on not letting others see the file links then you probably wouldn't want search engines to see them as well. A typical way of forbidding users from trying out such stuff is to have a specific page that flushes the file instead of linking directly to the file. E.g.,
Download
then in download.php you could check user permissions and make the browser download the file.
<?php
$file = 'file1234.pdf';
$file_url = 'http://www.test.com/files/' . $file;
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: attachment; filename="' . $file_url . '"');
readfile($file_url);
die();
?>
I think this is what you'll need.
Like, I have file on ftp http://site.com/download/file.zip
I download it by directly request from browser's address tab.
How can I count the number of requests of this file?
Or how do I remove the ability of such requests, so they should work only by php?
If anyone can get at the file by typing in a URL, you can't really count the accesses in any way other than reading the web server access log.
What you can do is:
Make the file itself inaccessible through any URL
Write a PHP script that "serves files" according to a query parameter passed to it
Keep a count from inside this script
Generally, the script in step 2 will look somewhat like this:
// Increase your "download count" by one
// $mimeType is the MIME type of the file you are serving
// e.g. "application/octet-stream"
// $filename is the name that the browser will offer as a default
// in the "save file" dialog
// $filepath is the real path of the file on your web server
header('Content-Type: '.$mimeType);
header('Content-Disposition: attachment; filename="'.$filename. '";' );
header('Content-Length: '.filesize($filepath));
readfile($filepath);
die;
You can create a download.php file that processes the download. I mean:
http://site.com/download.php?dl=file
And in such file you do whatever you want (log the timestamp, increase the number of downloads...). Then redirect to download the file.
You can remove the ability to direct access the file with a .htaccess file :
<FilesMatch ~ "^file\.zip$">
Deny from all
</FilesMatch>
If you are not a web guru. You can do what #Ale said by putting it in a file and then creating the file. In that file, put Google analytics and just track it from there. You'll have everything, even where they are, how many different people...so on.
Hope this helps.
I am working on a project where the user would be able to buy media files.
after the payment is processed I would like to allow them to download the file.
I guess it is safe to say that I should have a temporary link to the files. one that is linked to the IP of the user and perhaps a timestamp?
the problem is I dont know where to start with that.
First of all. is this the way to do it? if so..how do I proceed using php. ( i guess I dont need the exact script just hints on how to do it although if there is an existing script I would not mind)
thank you.
Since you are going to handle the file in PHP you might aswell use a login to check if the user has purchased the file, other than that the code should look a little like this:
header('Content-Type: application/force-download');
$file = new File(intval($_GET['id']));
$fileLocation = dirname(__FILE__) . "/../../upload/fileArchive/" . $file->id . "." . $file->type;
header('Content-Length:' . filesize($fileLocation));
header("Content-Disposition: inline; filename=\"".$file->name."\"");
$filePointer = fopen($fileLocation,"rb");
fpassthru($filePointer);
Taken from production and tested
I wouldn't tie the temporary link to an IP, it isn't very user-friendly solution.
Store the purchased media in a table for example:
Media id (This refers to an another table where the media details described)
Unique token (This will identificate the purchase)
Client id
Total downloads (Maybe you want to enable the download 5 times)
Token expiry (If you want to limit the access on this)
The download url must contain the unique token and some more data (user's hashed e-mail, etc.) to make the url more unique and more secure.
Sample URL: http://example.com/purchase/nc9o32ocrn8of4nv348/989934ov9344b
First hash holds the purchase itself while second one identifies the user. On successful identifying you can serve the file like Kristoffer said.
header('Content-Type: application/force-download');
$filee = "r.txt";
$fileLocation = dirname(__file__).'/the_sub_folder_for_file/'.$filee;
header('Content-Length:' . filesize($fileLocation));
header("Content-Disposition: inline; filename=\"".$filee."\"");
$filePointer = fopen($fileLocation,"rb");
fpassthru($filePointer);
I want to prevent downloading the zip file from my site. Only allowed for some times(at the time of payment). How can it me possible to expire that link or somthing like that to prevent my zip files.
How the rapidshare.com working? we can see the url but not possible to download ??
look at my answer and the comments on this question What is the best method to hide a file on a server? .. this is an idea and may work well for u , if u find it interesting and you agree with it
Edit:
As for how rapidshare works , i think u can hold the time when u want the actual download to happen in session and disable the link button with javascript on the UI , so even if they find the link and they goto it , you can check the time against the session time and redirect them elsewhere.
I am assuming only a registered member can download? You can store the time of payment in a database. Then the download can be accessed through a url like this: http://myhost/download-file.php?file=the-file-name.smthn
When the user goes to this url do all the credential checks like user name and password and the time he has paid. If he is allowed to download fetch the file and output to the browser like so:
$file = file_get_contents('dir-inaccessible-through-web/the-file-name.smthn');
header('Content-disposition: attachment; the-file-name.smthn');
// optionally
$size = strlen($file);
header('Content-length: ' . $size);
echo $file;
Note that the actual file is inaccessible to the web.