filedownload protect with .htaccess and php code

hoerts

Er der nogen som kan forklare mig hvad der står i denne tråd, som er skrevet i forummet for engelsk talende?

DarkViper

#19
Verlass Dich bitte nicht auf diesen Codeschnipsel:
<?php
# remove any attempt to back up your folders
$fichier str_replace('../','',WB_PATH.'/media/'.urldecode($_GET['file']));


Das ist sehr einfach zu umgehen. Es genügt, im Request anstatt des Slashes einen Backslash einzugeben. Oder aber anstatt '../' die Zeichenfolge '..././'.
Relativ sicher lässt sich ein extern eingegebener Pfad mittels realpath() und stripos() überprüfen.

<?php
$sMediaDir str_replace('\\''/'WB_PATH.'/media');
if( ($fichier realpath(WB_PATH.'/media/'.urldecode($_GET['file']))) !== false) {
$fichier str_replace('\\''/'$fichier);
if( stripos($fichier$sMediaDir) !== ) {
// ungueltiger Pfad
}
}else {
// ungueltiger Pfad
}

dieser Schnipsel bringt einen Fehler, wenn ein fehlerhafter Pfad übergeben wird oder die gesuchte Datei nicht innerhalb des Mediaverzeichnisses liegt.
[url=http://www.youtube.com/watch?v=tmzDAz6ZvFQ]Der blaue Planet[/url] - er ist nicht unser Eigentum - wir haben ihn nur von unseren Nachkommen geliehen[br]
[i]"You have to take the men as they are... but you can not leave them like that !" :-P [/i]
[i]Das tägliche Stoßgebet: [b]Oh Herr, wirf Hirn vom Himmel ![/b][/i]

Don Martin

Hallo Hans

Ich habe den folgenden Code benutzt um mein gesamtes Media Verzeichnis zu schützen. Ich hoffe diese Informationen helfen dir weiter.

<?php
// Secure download for WebsiteBaker
// original by VotreEspace see thread : https://forum.WebsiteBaker.org/index.php/topic,16282.msg106944.html#msg106944
// adapted and improved by PCWacht (march-2010)
//
// Use as : WB-securedownload.php?file=/media/thisdocument.doc
// 
//

if (isset($_GET['file'])) {
require("config.php");
if(!function_exists('mime_content_type')) {
function mime_content_type($filename) {
$mime_types = array(

'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'php' => 'text/html',
'css' => 'text/css',
'js' => 'application/javascript',
'json' => 'application/json',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',

// images
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',

// archives
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'exe' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'cab' => 'application/vnd.ms-cab-compressed',

// audio/video
'mp3' => 'audio/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',

// adobe
'pdf' => 'application/pdf',
'psd' => 'image/vnd.adobe.photoshop',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',

// ms office
'doc' => 'application/msword',
'rtf' => 'application/rtf',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',

// open office
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
);

$ext strtolower(array_pop(explode('.',$filename)));
if (array_key_exists($ext$mime_types)) {
return $mime_types[$ext];
}
elseif (function_exists('finfo_open')) {
$finfo finfo_open(FILEINFO_MIME);
$mimetype finfo_file($finfo$filename);
finfo_close($finfo);
return $mimetype;
}
else {
return 'application/octet-stream';
}
}
}
# code the url
$DEC urldecode($_GET['file']);
# set unallowed file, so nobody want to read /config.php or something
$unallowed_to_read = array('php','html','htm','htaccess');
#Check for images, they should be shown
$allowed_to_read = array('jpg','gif','png');
# remove any attempt to back up your folders
$fichier str_replace('../','',WB_PATH.'/media/'.urldecode($_GET['file']));
if(isset($_SESSION['USER_ID']) && SESSION_STARTED) {
if(file_exists($fichier) && (!in_array(end(explode('.',$fichier)),$unallowed_to_read))) {
header("Content-Type: " mime_content_type($fichier));
header("Content-Length: " filesize($fichier));
header("Content-Transfer-Encoding: binary");
header("Cache-Control: private");
header('Content-Disposition: attachment; filename="'.end(explode('/',$DEC)).'"');
echo file_get_contents($fichier);
} else {
# in case of absent file or attempt at hacking
echo 'oups';
}
} else {
/*if(file_exists($fichier) && (in_array(end(explode('.',$fichier)),$allowed_to_read))) {
header("Content-Type: " . mime_content_type($fichier));
header("Content-Length: " . filesize($fichier));
header("Content-Transfer-Encoding: binary");
header("Cache-Control: private");
header('Content-Disposition: attachment; filename="'.end(explode('/',$DEC)).'"');
echo file_get_contents($fichier);
} else {*/
# not logged  in and no picture? forbidden! 
header('HTTP/1.0 403 forbidden'TRUE403);
die('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
<html><head> 
<title>403 Forbidden</title> 
</head><body> 
<h1>FORBIDDEN</h1> 
<p>Without being logged in you dont have permission to fetch <b>'
.urldecode($_GET['file']).'</b> from this server.</p> 
<p><a href="/pages/deu_top/haendler-login.php">Click for login.</a></p>
</body></html> '
);
}
//}
}else{
header('Location: ./');
}

?>

Hans

Hallo Don

es wäre schön wenn Du die Code publizieren wolltest (Code ohne die veraltete Funktion). Ich bin ein kompletter NOOB und dankbar wenn du es mit mir (uns) teilen wolltest.

Und Verzeihung für mein "Deutsch" ;-)
Hans
Hans - Nijmegen - The Netherlands

Don Martin

#16
Ich hatte Probleme mit der mime_content_type($fichier) Funktion im Code. Diese ist eine "veraltet" Funktion.
Hilfe zu diesem Problem habe ich hier gefunden: https://forum.websitebaker.org/index.php/topic,16282.0.html

Hans Toolbox

#15
htaccess ist auf Apache beschränkt.
WebsiteBaker wird von mir empfohlen, weil es auf NGINX, LIGHTTPD oder *beliebig anderen http-Diensten funktioniert. Nicht anderes erwarte ich auch von einem PHP-CMS. Das ist eine hervorstechende Eigenschaft von WebsiteBaker, die leider nur von wenigen erkannt wird. WB läuft überall!
*: Serverspezifisches File-Management in WB ist überflüssig oder dürfte dann etwas umfangreicher ausfallen  :evil:
Wenn WB weiterhin unabhängig funktionieren soll ist Dein Vorschlag "php control" richtungsweisend. Zwei meiner Anwender haben auch  ihre Medien-Dateien unterhalb von wwwroot und verwalten diese über ein Script.

*=Textänderungen

Deine Lösung (htaccess/php) ist und bleibt natürlich trotzdem eine wirklich tolle (+tricky) !

There is an English forum here, I finish my German responses
[Die Beleidigung gegenüber mir wurde durch mich gelöscht, User wurde von mir ausgeschlossen - kweitzel]

pcwacht

QuoteWill man "Dateien schützen", die nicht für die Öffentlichkeit bestimmt sind, greift man zu entsprechenden Systemen.
Hmmm.. nicht meiner meinung, es gibt viele wegen zum schutzen

Einer ist dieses mit htaccess
Ein andere wäre zum beispiel ein directory zu machen ausser das html bereich und es mit php control zu ubergeben
Ein andere ist um die dateien ins database zu verlegen.

Genau dass ist das beste an WB, ins herz ist es einfach, aber powerfull genug um es mit ein wenig code dass zu machen was man braucht.
WB kann fast alles! Aber nicht nur mit die core, stimmt.

John
[url="http://www.ictwacht.nl"]http://www.ictwacht.nl[/url] = Dutch ICT info
[url="http://www.pcwacht.nl"]http://www.pcwacht.nl[/url] = My first
both still work in progress, since years.....

Hans Toolbox

Es gibt in diesem Falle keine Sicherheitsfragen, da man -wie schon gesagt- ein CMS vor sich hat.
Will man "Dateien schützen", die nicht für die Öffentlichkeit bestimmt sind, greift man zu entsprechenden Systemen.
[Die Beleidigung gegenüber mir wurde durch mich gelöscht, User wurde von mir ausgeschlossen - kweitzel]

Ralph

Hallo DarkViper,
wie ich schon gesagt habe, ist mein Englisch grotten schlecht aber wegen deinem Kommentar ... such a lot of people use this three characters CMS... without knowing about the real meaning of. bin ich ja hier um Fragen zu stellen. Was nützt ein Super CMS wenn es bestimmte Sicherheitsfragen gibt. Aber an dieser Stelle genug, ich denke Websitbaker mit seiner Gemeinschaft hat das Zeug früher oder Später zü den ganz Großen zu gehören.

Gruß Ralph

DarkViper

Quote
Was mich schon wundert ist, dass...

What always makes me surprised is, that...
... such a lot of people use this three characters CMS... without knowing about the real meaning of.   :?

Read this...
[url=http://www.youtube.com/watch?v=tmzDAz6ZvFQ]Der blaue Planet[/url] - er ist nicht unser Eigentum - wir haben ihn nur von unseren Nachkommen geliehen[br]
[i]"You have to take the men as they are... but you can not leave them like that !" :-P [/i]
[i]Das tägliche Stoßgebet: [b]Oh Herr, wirf Hirn vom Himmel ![/b][/i]

Ralph

Hallo John,
nochmals Danke für Deine Unterstützung, hab jetzt es jetzt zum Laufen gebracht (ein anderer Profi hat mich unterstützt :wink:).

Ich habe beide Dateien in das Root Verzeichnis der WB Installation kopiert, mit der .htaccsess war alles in Ordnung. In den WB-Secure Script hatten sich zwei kleine Fehler eingeschlichen. Im letzten else Zweig beim don't das Hochkomma und weiss ich nicht mehr daher hier meine geänderte Fassung

<?php
// Secure download for WebsiteBaker
// original by VotreEspace see thread : https://forum.WebsiteBaker.org/index.php/topic,16282.msg106944.html#msg106944
// adapted and improved by PCWacht (march-2010)
//
// Use as : WB-securedownload.php?file=/media/thisdocument.doc
// 
//

if (isset($_GET['file'])) {
require("config.php");
# code the url
$DEC urldecode($_GET['file']);
# set unallowed file, so nobody want to read /config.php or something
$unallowed_to_read = array('php','html','htm','htaccess');
#Check for images, they should be shown
$allowed_to_read = array('jpg','gif','png');
# remove any attempt to back up your folders
$fichier str_replace('../','',WB_PATH.'/media/'.urldecode($_GET['file']));
if(isset($_SESSION['USER_ID']) && SESSION_STARTED) {
if(file_exists($fichier) && (!in_array(end(explode('.',$fichier)),$unallowed_to_read))) {
header("Content-Type: " mime_content_type($fichier));
header("Content-Length: " filesize($fichier));
header("Content-Transfer-Encoding: binary");
header("Cache-Control: private");
header('Content-Disposition: attachment; filename="'.end(explode('/',$DEC)).'"');
echo file_get_contents($fichier);
} else {
# in case of absent file or attempt at hacking
echo 'oups';
}
} else {
/*if(file_exists($fichier) && (in_array(end(explode('.',$fichier)),$allowed_to_read))) {
header("Content-Type: " . mime_content_type($fichier));
header("Content-Length: " . filesize($fichier));
header("Content-Transfer-Encoding: binary");
header("Cache-Control: private");
header('Content-Disposition: attachment; filename="'.end(explode('/',$DEC)).'"');
echo file_get_contents($fichier);
} else {*/
# not logged  in and no picture? forbidden! 
header('HTTP/1.0 403 forbidden'TRUE403);
die('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
<html><head> 
<title>403 Forbidden</title> 
</head><body> 
<h1>FORBIDDEN</h1> 
<p>Without being logged in you dont have permission to fetch <b>'
.urldecode($_GET['file']).'</b> from this server server.</p> 
<p><a href="/vWB_Verzeichnis/account/login.php">Click for login.</a></p>
</body></html> '
);
}
//}
}else{
header('Location: ./');
}
?>



Was mich schon wundert ist, dass diesem Problem der Verzeichnissicherheit hier nicht mehr Aufmerksamkeit geschenkt wird bzw. scheint es den Nutzern noch nicht augefallen zu sein, dass man über den absoluten Pfad alles bekommen kann. Egal Problem gelöst , nehmen wir die nächten in Angriff. Ansonsten macht mir WB sehr viel Spass, man muß sich eben reindenken. Also Danke für Eure Hilfe bis bald

Ralph

Ralph

Thanks John,

in the. htaccess I had before / WB securedownload.php still do .. / or he calls on not. Now looks like this:

Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^media/(.*)\.(.*)$ ../WB-securedownload.php?file=$1.$2 [R,L]

The / WB-securedownload.php (I have no changes from you) creates now this url:

Url: http://www.xyz.de/WB-securedownload.php?file=download_gallery/xy.pdf

When you call, whether logged in or not here comes this error:

Bad Request 400
Your browser sent a request that this server could not understand.
Client sent malformed Host header

Can it deal here with an error:
header("Content-Type: " . mime_content_type($fichier));
Because there are pdf?

If I put both scripts in the WB folder and the two .. remove, then comes the error "not found".

I know now go no further

pcwacht

So mit RewriteBase /
die url rewriting geht gut?

Sie bekommen etwas als : http://www.xyz.de/WB-securedownload.php?file=download_gallery/xy.pdf


Die Bad Request komt von die WB-securedownload.php ??
sei sicher das die WB-securedownload stimmt mit dass wass ich als ersten geschrieben habe.
Wenn nur etwas fehlt bekommt du das

Sie könte es aber testen mit:
WB-securedownload.php?file=einer.pdf


Spass,
John
[url="http://www.ictwacht.nl"]http://www.ictwacht.nl[/url] = Dutch ICT info
[url="http://www.pcwacht.nl"]http://www.pcwacht.nl[/url] = My first
both still work in progress, since years.....

Ralph

with RewriteBase / sees the URL as it should be like this but it is a Error 400 "Bad Request
Your browser sent a request that this server could not understand.
Client sent malformed Host header"

and now?  :x

pcwacht

RewriteBase /
is needed as well

try:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^media/(.*)\.(.*)$ /WB-securedownload.php?file=$1.$2 [R,L]


John
[url="http://www.ictwacht.nl"]http://www.ictwacht.nl[/url] = Dutch ICT info
[url="http://www.pcwacht.nl"]http://www.pcwacht.nl[/url] = My first
both still work in progress, since years.....

pcwacht

Schau dir die .htaccess nach weil die linke:

http://www.xyz.de/var/www/vhosts/xyz.de/WB-securedownload.php?file=download_gallery/xy.pdf

soll

http://www.xyz.de/WB-securedownload.php?file=download_gallery/xy.pdf

sein

Ich glaube die .htaccess macht wass falsch, vielleicht hatte es etwas mit symlinks zu machen.

versuche mal diese .htaccess

QuoteOptions +FollowSymlinks
RewriteEngine on
RewriteRule ^media/(.*)\.(.*)$ /WB-securedownload.php?file=$1.$2 [R,L]

Wenn es nuhr fur einer unterordner unter media geben soll:

QuoteOptions +FollowSymlinks
RewriteEngine on
RewriteRule ^media/unterordner/(.*)\.(.*)$ /WB-securedownload.php?file=$1.$2 [R,L]

Ich hoffe du schaft es.

Spass,
John


[url="http://www.ictwacht.nl"]http://www.ictwacht.nl[/url] = Dutch ICT info
[url="http://www.pcwacht.nl"]http://www.pcwacht.nl[/url] = My first
both still work in progress, since years.....

kweitzel

That does sound as if you have the WB_URL in front of the WB_PATH ... did you just copy the script and the htaccess or did you change it?

cheers

Klaus

Ralph

Hi John,
I have a little now can achieve. But after calling a file, whether loggin or not I get a 404 Not Found, and the URL that is generated looks like this:
http://www.xyz.de/var/www/vhosts/xyz.de/WB-securedownload.php?file=download_gallery/xy.pdf

please help me

Ralph

Ralph

Hallo John,

ich habe versucht Dein Beispiel in meine Seite einzubauen, leider ohne Erfolg. In dem Media Ordner hab ich PDF Dateien (auch Unterordner). Ich will verhindern das man ohne Anmeldung auf die PDF zugreifen kann wenn man den direkten Pfad kennt.

Die Datei 'WB-securedownload.php' hab ich ins Rootverzeichniss (www.xyz.de/WB-securedownload.php) des Webservers kopiert und die htaccess in das Rootverzeichnis der WebsiteBaker Installation.

Was mache ich falsch?

Leider ist mein Englisch sooo schlecht, das mir nichts übrig bleibt als in Deutsch anzufragen ob Du mir helfen kannst.

Gruß
Ralph

pcwacht

You have some files wich are only for the registred visitors and you don't want any non registred visitor to get the file

Steps:
1 - create a file in the root of your installation and call it : WB-securedownload

<?php
// Secure download for WebsiteBaker
// original by VotreEspace see thread : https://forum.WebsiteBaker.org/index.php/topic,16282.msg106944.html#msg106944
// adapted and improved by PCWacht (march-2010)
//
// Use as : WB-securedownload.php?file=/media/thisdocument.doc
// 
//
if (isset($_GET['file'])) {
require("config.php");
# code the url
$DEC urldecode($_GET['file']);
# set unallowed file, so nobody want to read /config.php or something
$unallowed_to_read = array('php','html','htm','htaccess');
#Check for images, they should be shown
$allowed_to_read = array('jpg','gif','png');
# remove any attempt to back up your folders
$fichier str_replace('../','',WB_PATH.'/media/'.urldecode($_GET['file']));
if(isset($_SESSION['USER_ID']) && SESSION_STARTED) {
if(file_exists($fichier) && (!in_array(end(explode('.',$fichier)),$unallowed_to_read))) {
header("Content-Type: " mime_content_type($fichier));
header("Content-Length: " filesize($fichier));
header("Content-Transfer-Encoding: binary");
header("Cache-Control: private");
header('Content-Disposition: attachment; filename="'.end(explode('/',$DEC)).'"');
echo file_get_contents($fichier);
} else {
# in case of absent file or attempt at hacking
echo 'oups';
}
} else {
if(file_exists($fichier) && (in_array(end(explode('.',$fichier)),$allowed_to_read))) {
header("Content-Type: " mime_content_type($fichier));
header("Content-Length: " filesize($fichier));
header("Content-Transfer-Encoding: binary");
header("Cache-Control: private");
header('Content-Disposition: attachment; filename="'.end(explode('/',$DEC)).'"');
echo file_get_contents($fichier);
} else {
# not logged  in and no picture? forbidden! 
header('HTTP/1.0 403 forbidden'TRUE403);
die('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
<html><head> 
<title>403 Forbidden</title> 
</head><body> 
<h1>FORBIDDEN</h1> 
<p>Without being logged in you don'
t have permission to fetch <b>'.urldecode($_GET['file']).'</bfrom this server server.</p
<p><a href="/account/login.php">Click for login.</a></p>
</body></html');
}
}
}else{
header('
Location: ./');
}
?>



2 - create a .htaccess file in the foor of your wb installation in it:

RewriteEngine on
RewriteRule ^media/(.*)\.(.*)$ /WB-securedownload.php?file=$1.$2 [R,L]

tip - - change the path /WB-securedownload to /wb-path/WB-securedownload if needed

The way it works
1 with a htaccess rewriterule we test to see if something is needed from teh media folder, if so redirect it to a script so we can test it
examplë:
http://www.someserver.com/media/somefolder/somefile.doc
will become:
http://www.someserver.com/WB-securedownload?file=somefolder/somefile.doc

The script in WB-securedir will test to see if:
1 - the parameter file was given
2 - if user is logged in
3 - if it is a picture, then show it


Have fun,
John
[url="http://www.ictwacht.nl"]http://www.ictwacht.nl[/url] = Dutch ICT info
[url="http://www.pcwacht.nl"]http://www.pcwacht.nl[/url] = My first
both still work in progress, since years.....