Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protect downloads on remote server

Tags:

php

wordpress

I have 2 servers. On Server 1 I have a WordPress website. On Server 2 I have large .zip files that I want members from the WordPress site to be able to download.

How do I authenticate these users so that only people that are members of the website can download files from the second server?

Is it possible to use PHP so that only referrers from my domain have access to the files?

Note: The links to download the files are protected on the wordpress site so that non-logged in users are redirected to a join page. However, current and ex-members would still know the directory where the downloads are and could possibly download the files or share the links.

like image 925
user1446650 Avatar asked Jun 09 '12 20:06

user1446650


2 Answers

There are several ways of doing this. The most secure way would be to have some back-end communication between Server 1 & Server 2. But here is an easy alternative:

Server 2 : download.php

<?PHP
 $file = $_GET['f'];
 $code = $_GET['c']; 
 $ip = $_SERVER['REMOTE_ADDR'];

 if ($code != md5($ip . 'salt')) {
    die('authentication denied');
 }

 if(!file)
 {
     die('file not found');
 }

 // Set headers
 header("Cache-Control: public");
 header("Content-Description: File Transfer");
 header("Content-Disposition: attachment; filename=$file");
 header("Content-Type: application/zip");
 header("Content-Transfer-Encoding: binary");

 // Read the file from disk
 readfile('/files/downloads/' . $file);

?>

Server 1 : Download link

<?PHP
 echo '<a href="http://server2.com/download.php?f=text.txt&c=' . md5($_SERVER['REMOTE_ADDR'] . 'salt') / '">Download File</a>';
?>

This system works by creating a link that can only be used on the IP it was generated for. So a registered user cannot share the link elsewhere. It's not the most secure thing but it's easy to implement and will work.

like image 130
Patrick Lorio Avatar answered Nov 01 '22 20:11

Patrick Lorio


Some neat solution may be to use a token system based on current time. You can take current hour of the day and hash it with some salt, and put it in the query string as token. Than php script on second server may check if query-string hash is same, as hash generated for current hour of the day with same salt on server side.

To be sure that user won't hit the hour-switch time you can check for previous hour hash too.

It makes you certain that file url won't be available for more than two hours with guaranteed time of availability of one hour.

On server 1:

<?php
echo '<a href="server2.com/download.php?token='.md5(date('G')+'secret_word').'&file=file.zip">Link</a>';
?>

On server 2:

<?php
current_hour_hash = md5( date('G').'secret_word' );
previous_hour_number = ( int(date('G')) - 1 ) % 24;
previous_hour_hash = md5( str(previous_hour_number).'secret_word' );
if($_GET['token']!= current_hour_hash and $_GET['token']!= previous_hour_hash){
    die();
}else{
    ... //code sending file here
}
like image 25
yakxxx Avatar answered Nov 01 '22 21:11

yakxxx