I have a Weblication which provides access to certain pages only to some users. Now there are some files linked on these pages. If someone has the URL everyone can access these files (in this case the search engines). This should be changed! How can I protect such a directory? I thought about two possibilites:
Are there any other possibilities?
Taken and translated from this link (but is only available in the WaybackMachine).
With the help of the function wCheckPermissionViewFile
php files can be personalized. It is sufficient to perform the permission check in the header of a file to suppress the output. If other file types should be personalised (e.g. ZIP, PDF, ...), wPermission.cgi
or a custom php file can be used.
To save the editor some work for writing wPermission.cgi
before every personalised link to a binary file, instead the Apache module mod_rewrite
can be used. With this it is possible to convert every accessed link before execution. For example you could define that wPermission.cgi
is in front of each webserver call. The direct execution could also be redirected with the help of a php file (no wPermission.cgi
necessary).
.htaccess
file via check from Perl (wPermission.cgi
)#Alle Dateien mit angegebener Endung über wPermission.cgi aufrufen.
RewriteEngine on
RewriteCond %{REQUEST_URI} .pdf$ [NC,OR]
RewriteCond %{REQUEST_URI} .doc$ [NC,OR]
RewriteCond %{REQUEST_URI} .xls$ [NC,OR]
RewriteCond %{REQUEST_URI} .ppt$ [NC,OR]
RewriteCond %{REQUEST_URI} .pps$ [NC,OR]
RewriteCond %{REQUEST_URI} .zip$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpg$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpeg$ [NC,OR]
RewriteCond %{REQUEST_URI} .png$ [NC,OR]
RewriteCond %{REQUEST_URI} .gif$ [NC]
RewriteRule (.*) /cgi-bin/wPermission.cgi?file=/de/dokumente/$1
.htacces
file via check from PHP (e.g. download.php, see below)#Alle Dateien mit angegebener Endung über die angegebene PHP-Datei aufrufen.
RewriteEngine on
RewriteCond %{REQUEST_URI} .pdf$ [NC,OR]
RewriteCond %{REQUEST_URI} .doc$ [NC,OR]
RewriteCond %{REQUEST_URI} .xls$ [NC,OR]
RewriteCond %{REQUEST_URI} .ppt$ [NC,OR]
RewriteCond %{REQUEST_URI} .pps$ [NC,OR]
RewriteCond %{REQUEST_URI} .zip$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpg$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpeg$ [NC,OR]
RewriteCond %{REQUEST_URI} .png$ [NC,OR]
RewriteCond %{REQUEST_URI} .gif$ [NC]
RewriteRule (.*) /de/download.php?path=/de/dokumente/$1
If you would like to personalise all PDF and ZIP files within the directory /de/dokumente
without changing the links, you could put a .htaccess
file into that directory. In this file the redirect rules are defined.
The rules can be extended with arbitrary file extensions, NC
stands for non case sensitive. Be aware that the rules are also inherited onto sub directories.
The binary files itself have to be checked in and provided with the according personalisation.
If you would like to check if the file is in a valid publishing time period (e.g. online or offline), then do the check before the permission check via PHP API wIsOnline
.
.htacces
file via check from PHP (e.g. download.php)"<?php
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Dieses Skript erzwingt den Download von Dokumenten. PDF, DOC, XLS und PPT Dokumente werden je nach Browser angezeigt.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Einlesen der Weblication(r) 4.x API:
require_once ($_SERVER["DOCUMENT_ROOT"]."/weblication/lib/WAPI/WAPI.inc");
$filenameRel = str_replace("..", "", $_GET['path']);
$filename = $_SERVER['DOCUMENT_ROOT'].$filenameRel;
if(preg_match("/\.\w+$/", $filename) && !preg_match("/\.(php|php5|php4|xml|xsl|cgi|pl)$/", $filename) && !preg_match("/\/weblication\//", $filename) && file_exists( $filename ) ){
if(wCheckPermissionViewFile($filenameRel) == 1){
header("Pragma: no-cache");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
if(preg_match("/\.pdf/i", $filenameRel)){
header("Content-Type: application/pdf");
}
else if(preg_match("/\.doc/i", $filenameRel)){
header("Content-Type: application/msword");
}
else if(preg_match("/\.xls/i", $filenameRel)){
header("Content-Type: application/msexcel");
}
else if(preg_match("/\.ppt/i", $filenameRel)){
header("Content-Type: application/mspowerpoint");
}
else if(preg_match("/\.pps/i", $filenameRel)){
header("Content-Type: application/mspowerpoint");
}
else if(preg_match("/\.jpg/i", $filenameRel)){
header("Content-Type: image/jpg");
}
else if(preg_match("/\.jpeg/i", $filenameRel)){
header("Content-Type: image/jpeg");
}
else if(preg_match("/\.png/i", $filenameRel)){
header("Content-Type: image/png");
}
else if(preg_match("/\.gif/i", $filenameRel)){
header("Content-Type: image/gif");
}
else{
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
}
readfile($filename);
}
else{
print "Permission Denied!";
}
}
else {
print 'Sorry, wrong path or file does not exist on the server!';
print '<br/><a href="javascript:history.back();">back</a>';
}
exit;
?>
For newer versions of Weblication
this link could help. It is in German, because the manufacturers main language is German.
You could store all of your file in a non public directory and then write a page (much like you say with download.php?file=xxx) that checks the user has permission to access the file and then output to the browser.
Edit:
As you are using a CMS, I would presume that the user has a nice GUI that they can click to choose the file they wish to insert/link to? If this is the case, you could probably find the code that it uses to create the link and then prepend http://www.whatever.com/download.php?file=
to the filename which would then route the download through your script.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With