In WordPress nutze ich zum Darstellen meiner Bilder das Gallery-Plugin “NextGEN Gallery“.
Da ich nicht will das Hinz und Kunz meine Bilder betrachten können, habe ich die Seiten vor Fremdzugriff geschützt.
Zuerst habe ich es mit den WordPress eigenen Bordmitteln (Visibility entsprechend geändert) und dann mit einem Plugin “Page Restrict” probiert.
Das Problem was mir dabei aufgefallen ist:
Es wird zwar die jeweilige Seite geschützt, man muss sich also entsprechend WordPress gegenüber authentifizieren, aber die eingebetteten Inhalte bleiben davon unberührt.
D.h. angemeldete Benutzer können zum Beispiel die Links zu Bildern per E-Mail verrschicken und den Schutz somit für Fremde umgehen.
Nach ein bisschen recherchieren habe ich leider festgestellt, dass das auch bei großen sozialen Netzwerken wie facebook und lokalisten der Fall ist!!!
Wenn hier jemand die URL zu einem in facebook oder lokalisten eingefügten Bild kopiert, sich ausloggt und in die URL aufruft, wird das Bild trotzdem angezeigt!!!
Dieses Sicherheitsproblem lässt sich meiner Meinung nach nur lösen, indem die Bilder nicht direkt aufgerufen werden, sondern eine php-Abfrage dazwischen gelegt wird.
Der php Code muss prüfen, ob das Bild ausgeliefert werden darf oder nicht.
Kurze Erklärung zu NextGEN Gallery:
Ich gehe bei meiner Ausführung davon aus, dass die NextGEN Gallerien im Verzeichnis wp-content/gallery abgelegt sind. Das ist die Standardeinstellung.
Folgendes Schritte müssen dafür durchgeführt werden:
1) Das Original-Verzeichnis zu den Gallerien muss per .htaccess Datei vor dem Zugriff geschützt werden.
# Disable Directory Browsing Options All -Indexes SetEnvIf Request_URI ".*/wp-content/gallery/.*" protected # Auth directives AuthUserFile <path_to_your_httpdocs_directory>/.htpasswd AuthName "Password Protected" AuthType Basic # Setup a deny/allow Order Deny,Allow # Deny from everyone Deny from all # except if either of these are satisfied Satisfy any # 1. a valid authenticated user Require valid-user # 2. the "require_auth" var is NOT set Allow from env=!protected
Die .htpasswd Datei müsst ihr natürlich noch anlegen und füllen.
Damit ist das Verzeichnis der kompletten Gallerien schon einmal geschützt.
Das könnte jetzt eigentlich auch schon so bleiben, nur ist die htaccess-Abfrage nicht wirklich schön. Aus diesem Grund müssen noch ein paar Schritte durchgeführt werden.
2) Beim Ausliefern des HTML-Codes schreiben wir via Apache-Modul alle URLs welche auf die Gallerien verweisen um, aber nur, wenn wir uns nicht im WordPress Admin-Bereich befinden.
(Dazu wird das Apache-Modul mod_substitute benötigt)
<LocationMatch ^((?!wp-admin).)*$ > AddOutputFilterByType SUBSTITUTE text/html Substitute "s|wp-content/gallery/|wp-content/gallery-images/|ni" </LocationMatch>
Mit dieser Regel wird aus dieser URL:
http://<your-domain>/wp-content/gallery/dummy_gallery/abc123.jpg
dann diese:
http://<your-domain>/wp-content/gallery-images/dummy_gallery/abc123.jpg
Wird jetzt eine so modifizierte HTML-Seite aufgerufen, bekommt der Besucher kein einziges Bild zu sehen. Das gallery-images Verzeichnis existiert nicht.
Darum brauchen wir eine zusätzliche Erweiterung in der .htaccess Datei.
3) gallery-images via .htaccess auf php-Datei mappen
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} wp-admin
RewriteRule ^wp-content/gallery-images\/(.*) wp-content/gallery/$1 [NC]
RewriteCond %{HTTP_REFERER} !wp-admin
RewriteRule ^wp-content/gallery-images\/(.*) renderImageFromFile.php?imgUrl=$1 [NC]
</IfModule>
4) Jetzt noch die php-Datei erzeugen
<?php
// include wordpress functions needed for user validation
require_once('./wp-config.php');
$dummy_image = "dummy_image.jpg";
$rootpath = 'wp-content/gallery/';
$imgpath = $rootpath . $_GET['imgUrl'];
//check if file exists
if(!file_exists($imgpath))
{
exit;
}
// visitor needs to be logged in
if(!is_user_logged_in()) //this is a wordpress function
{
header('Content-Type: image/jpeg');
header("Content-Length: " . filesize($dummy_image));
$fp = fopen($dummy_image, 'rb');
fpassthru($fp);
fclose($fp);
exit;
}
// check referer url domain
$refURL = parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST);
if($refURL != '<your_domain>')
{
header('Content-Type: image/jpeg');
header("Content-Length: " . filesize($dummy_image));
$fp = fopen($dummy_image, 'rb');
fpassthru($fp);
fclose($fp);
exit;
}
// Get the mimetype for the file
$finfo = finfo_open(FILEINFO_MIME_TYPE);
// return mime type ala mimetype extension
$mime_type = finfo_file($finfo, $imgpath);
finfo_close($finfo);
switch ($mime_type){
case "image/jpeg":
// Set the content type header - in this case image/jpg
header('Content-Type: image/jpeg');
break;
case "image/png":
// Set the content type header - in this case image/png
header('Content-Type: image/png');
break;
case "image/gif":
// Set the content type header - in this case image/gif
header('Content-Type: image/gif');
break;
}
header("Content-Length: " . filesize($imgpath));
$fp = fopen($imgpath, 'rb');
fpassthru($fp);
fclose($fp);
?>
Mit diesen kleinen Änderungen sind alle Gallerie Bilder der WordPress Seite vor fremdem Zugriff geschützt, auch wenn Links zu den einzelnen Bildern verteilt werden.