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', TRUE, 403);
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']).'</b> from 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
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
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
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
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
RewriteBase /
is needed as well
try:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^media/(.*)\.(.*)$ /WB-securedownload.php?file=$1.$2 [R,L]
John
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
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
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
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', TRUE, 403);
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
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... (https://forum.websitebaker.org/index.php/topic,18596.msg124072.html#msg124072)
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
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.
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
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
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
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
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', TRUE, 403);
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: ./');
}
?>
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) !== 0 ) {
// 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.
Er der nogen som kan forklare mig hvad der står i denne tråd, som er skrevet i forummet for engelsk talende?