Jump to content

how to prevent direct download of files in php

- - - - -

  • Please log in to reply
6 replies to this topic

#1
mutago

mutago

    Programmer

  • Members
  • PipPipPipPip
  • 102 posts
Hi everyone, i have file that can be download using this link eg "http://www.domain.com/data/book.pdf"
my authentication page before download is http://www.domain.com/data/login.php"
okay how do i prevent the users from direct download of my files using direct url "http://www.domain.com/data/book.pdf"
thanks

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
If you do something like: http://www.domain.co...p?file=book.pdf, then you can have download.php validate the login data, and hand the file from a non-accessible location.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
Aetion

Aetion

    Newbie

  • Members
  • Pip
  • 4 posts
Hi,
I would like to add to this.

With your link "http://www.domain.com/data/book.pdf", you are providing a direct link to the pdf file, so there is no question of authentication.

So as WingedPather has said above, If you request the download via a php script then you can check if the user is logged in, and then return the pdf file as the response.

#4
mutago

mutago

    Programmer

  • Members
  • PipPipPipPip
  • 102 posts
Thanks and can you please illustrate with example on how my link should look like the one you stated
thanks

#5
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
A quick search gave me this:
How to serve big files through PHP | Teddy.fr
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#6
mikenco

mikenco

    Newbie

  • Members
  • Pip
  • 5 posts
Another idea could be to create a .htaccess file in that directory containing something like this?

Redirect /data/book.pdf /data/login.php

But this will ONLY help if your users are already looking for the file at /data/book.pdf . Your login.php file would have to direct the users to a new location of the pdf file. Otherwise it might create a loop where your login.php file keeps getting redirected by the .htaccess file.

(Might not help, but just an idea :))

EDIT: You could publish "Download this file from http://www.yourdomain.com/yourfile.pdf", but make sure that the PDF file is elsewhere, and that your login.php directs them to the correct location.. make sense? :)

#7
mutago

mutago

    Programmer

  • Members
  • PipPipPipPip
  • 102 posts
Thanks a lot: i have tried what wingedpather said just run this code below. it works fine and was able to prevent direct download
from unauthorised users.

download1.php

<?php



// Allow direct file download (hotlinking)?

// Empty - allow hotlinking

// If set to nonempty value (Example: example.com) will only allow downloads when referrer contains this text

define('ALLOWED_REFERRER', '');


// Download folder, i.e. folder where you keep all files for download.

// MUST end with slash (i.e. "/" )

define('BASE_DIR','C:/datafiles/');


// log downloads?  true/false

define('LOG_DOWNLOADS',true);


// log file name

define('LOG_FILE','downloads.log');


// Allowed extensions list in format 'extension' => 'mime type'

// If myme type is set to empty string then script will try to detect mime type 

// itself, which would only work if you have Mimetype or Fileinfo extensions

// installed on server.

$allowed_ext = array (


  // archives

  'zip' => 'application/zip',


  // documents

  'pdf' => 'application/pdf',

  'doc' => 'application/msword',

  'xls' => 'application/vnd.ms-excel',

  'ppt' => 'application/vnd.ms-powerpoint',

  

  // executables

  'exe' => 'application/octet-stream',


  // images

  'gif' => 'image/gif',

  'png' => 'image/png',

  'jpg' => 'image/jpeg',

  'jpeg' => 'image/jpeg',


  // audio

  'mp3' => 'audio/mpeg',

  'wav' => 'audio/x-wav',


  // video

  'mpeg' => 'video/mpeg',

  'mpg' => 'video/mpeg',

  'mpe' => 'video/mpeg',

  'mov' => 'video/quicktime',

  'avi' => 'video/x-msvideo'

);




####################################################################

###  DO NOT CHANGE BELOW

####################################################################


// If hotlinking not allowed then make hackers think there are some server problems

if (ALLOWED_REFERRER !== ''

&& (!isset($_SERVER['HTTP_REFERER']) || strpos(strtoupper($_SERVER['HTTP_REFERER']),strtoupper(ALLOWED_REFERRER)) === false)

) {

  die("Internal server error. Please contact system administrator.");

}


// Make sure program execution doesn't time out

// Set maximum script execution time in seconds (0 means no limit)

set_time_limit(0);


if (!isset($_GET['f']) || empty($_GET['f'])) {

  die("Please specify file name for download.");

}


// Nullbyte hack fix

if (strpos($_GET['f'], "\0") !== FALSE) die('');


// Get real file name.

// Remove any path info to avoid hacking by adding relative path, etc.

$fname = basename($_GET['f']);


// Check if the file exists

// Check in subfolders too

function find_file ($dirname, $fname, &$file_path) {


  $dir = opendir($dirname);


  while ($file = readdir($dir)) {

    if (empty($file_path) && $file != '.' && $file != '..') {

      if (is_dir($dirname.'/'.$file)) {

        find_file($dirname.'/'.$file, $fname, $file_path);

      }

      else {

        if (file_exists($dirname.'/'.$fname)) {

          $file_path = $dirname.'/'.$fname;

          return;

        }

      }

    }

  }


} // find_file


// get full file path (including subfolders)

$file_path = '';

find_file(BASE_DIR, $fname, $file_path);


if (!is_file($file_path)) {

  die("File does not exist. Make sure you specified correct file name."); 

}


// file size in bytes

$fsize = filesize($file_path); 


// file extension

$fext = strtolower(substr(strrchr($fname,"."),1));


// check if allowed extension

if (!array_key_exists($fext, $allowed_ext)) {

  die("Not allowed file type."); 

}


// get mime type

if ($allowed_ext[$fext] == '') {

  $mtype = '';

  // mime type is not set, get from server settings

  if (function_exists('mime_content_type')) {

    $mtype = mime_content_type($file_path);

  }

  else if (function_exists('finfo_file')) {

    $finfo = finfo_open(FILEINFO_MIME); // return mime type

    $mtype = finfo_file($finfo, $file_path);

    finfo_close($finfo);  

  }

  if ($mtype == '') {

    $mtype = "application/force-download";

  }

}

else {

  // get mime type defined by admin

  $mtype = $allowed_ext[$fext];

}


// Browser will try to save file with this filename, regardless original filename.

// You can override it if needed.


if (!isset($_GET['fc']) || empty($_GET['fc'])) {

  $asfname = $fname;

}

else {

  // remove some bad chars

  $asfname = str_replace(array('"',"'",'\\','/'), '', $_GET['fc']);

  if ($asfname === '') $asfname = 'NoName';

}


// set headers

header("Pragma: public");

header("Expires: 0");

header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

header("Cache-Control: public");

header("Content-Description: File Transfer");

header("Content-Type: $mtype");

header("Content-Disposition: attachment; filename=\"$asfname\"");

header("Content-Transfer-Encoding: binary");

header("Content-Length: " . $fsize);


// download

// @readfile($file_path);

$file = @fopen($file_path,"rb");

if ($file) {

  while(!feof($file)) {

    print(fread($file, 1024*8));

    flush();

    if (connection_status()!=0) {

      @fclose($file);

      die();

    }

  }

  @fclose($file);

}


// log downloads

if (!LOG_DOWNLOADS) die();


$f = @fopen(LOG_FILE, 'a+');

if ($f) {

  @fputs($f, date("m.d.Y g:ia")."  ".$_SERVER['REMOTE_ADDR']."  ".$fname."\n");

  @fclose($f);

}


?>

TO FETCH THE FILE from directory
download2.php


<html><head>

</head><body>



<a href="download2.php?f=ebook1.pdf">Download Now</a>



</body></hml>





everything works fine. okay now I want the download2.php link to generate random unique ids in the links during download
but the pdf file refuses to download. below is what am trying to do

<html><head>

</head><body>

<?

$f=rand(1000,5000);

print "<a href=venus.php?$f=ebook1.pdf>Download book</a>"; 




?>

</body></hml>


any help please

---------- Post added at 02:12 PM ---------- Previous post was at 02:05 PM ----------

Sorry below is the intended link any help please


print "<a href=download1.php?$f=ebook1.pdf>Download book</a>"; 









1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users