Download - Paradoxis/PHP-security-classes GitHub Wiki
Download - Source code exposure / Information leakage
The download class is made simply to make it easy and secure for developers to allow users to download files that are outside the website root, or are simply forbidden for regular users.
The big issue with allowing users to download files, is that if a developer wishes to make this dynamic; it poses a great security risk, which is that if a user adds ../
or ..\
on windows machines, they could potentially force-download sensitive files which could include source code or user data and even hard coded passwords.
This is why a class was made to allow developers to restrict users from which files they get to download.
NOTICE: Using this class to download files that are already outside the web-root does not help much, unless you set restrictions on the files / folders so users cannot access them, the entire idea is that these downloads are made to be private, but you can use this to make simple download buttons.
Usage
To use this class, simply include it from the repository and initialize a new Download object.
// Include class
require_once('PHP-security-classes/src/Download.php');
// Give the class a nice name
use \Paradoxis\Security\Download as Download;
// Initialize a new Download object, with the minimal requirements.
$Download = new Download($_GET['file']);
$Download->validate();
$Download->download();
This initiates a new Download object, which accepts the $_GET['file']
parameter for users to download files, assuming the key has been set, for best results use the XSS class to get the $_GET
parameter like so: XSS::getGetValue('file')
Specifying a target path
By default the script assumes the target folder is the folder in which the object was initiated, you can specify a different one like so:
// Initialize a new Download object, and pass a folder in which users should download their files.
// In this example, we have set it to "/home/john/downloadable_files/"
$Download = new Download($_GET['file'], '/home/john/downloadable_files/');
Specifying allowed file extensions
By default, the user can now download all files in this folder with the following extensions: (assuming they know the file names)
pdf
, jpg
, jpeg
, png
, gif
, zip
If however, you wish to specify different extensions for the files that users can download, you can do that like so:
// Initiate a new Download object with a custom set of file extensions users can download
// The download now only accepts mov, pdf, zip and rar files to be downloaded by the user.
$Download = new Download($_GET['file'], '/home/john/downloadable_files/', array('mov', 'pdf', 'zip', 'rar'));
Specifying a whitelist of filenames
The developer can put more restrictions on the download, if for instance a user is only allowed to download certain PDF files that belong to them, you can add a whitelist of files they are allowed to download through an additional array.
// Initialize a new Download object, this time the user is only allowed to download 1 pdf named:
// - invoice_2014_12_05.pdf
$Download = new Download($_GET['file'], '/home/john/downloadable_files/', array('pdf'), array('invoice_2014_12_05.pdf'));
$Download->validate();
$Download->download();
Checking for errors
If the user's download fails, you might want to check if the script ran into any problems. (Yep, there's a function for that) You can check for errors and display them to the user like so:
// Initialize Download object, this would result in an "Illegal file extension" error.
$Download = new Download('index.php', null, array('jpg', 'mov'));
// This block of code would check the file extensions and allow the user
// to download their software, however since the filename was renamed to "index.php"
// the user cannot download this file, thus creating an error.
if ($Download->validate() && $Download->download()) {
exit;
}
// Not successful, lets display the errors to the user!
elseif($Download->hasErrors()) {
print_r($Download->getErrors());
}