PHP-Fehlermeldungen mit .htaccess steuern

Grundsätzlich kann es zu einem Sicherheitsrisiko werden PHP-Fehlermeldungen auf der Website anzeigen zu lassen, da mit Rückschlüssen auf den Code, die Verzeichnisstruktur oder Datenbankstruktur der Fehler ausgenutzt werden könnte.
Mit folgenden Einträgen in der .htaccess lassen sich die PHP-Fehlermeldungen unterdrücken.

php_flag display_startup_errors off
php_flag display_errors off
php_flag html_errors off
php_value docref_root 0
php_value docref_ext 0

Sinnvoll ist es hingegen die Fehler in eine Logdatei zu schreiben:

php_flag  log_errors on
php_value error_log  /path/to/website/PHP_errors.log

Sinnvoll ist es zudem den Zugriff über den Browser auf die Logdatei zu verbieten:


 Order allow,deny
 Deny from all
 Satisfy All

Mit Apache Hotlinking und Bilderklau unterbinden

Als Webmaster freut man sich über eingehende Links, denn schließlich steigt damit die Linkpopularität. Werden jedoch einzelne Inhalte wie beispielsweise Bilder in Foren direkt per Link eingebunden, können sich daraus erhebliche Probleme ergeben: Ist das Forum stark frequentiert und das eingebundene Foto relativ groß, kann der so generierte Traffic schnell bedrohliche Ausmaße annehmen.

Keine Chance für Trafficdiebe

Wäre es nicht elegant Trafficdieben das Handwerk zu legen, indem wir Ihnen statt dem verlinkten Bild eine andere Datei unterschieben? Statt des gewünschten Fotos könntest du den Contentdieb auf diese Weise unfreiwillig ein Werbebanner für deine eigene Website einbinden lassen.

stoppt_contentdiebe

Voraussetzung für die beschriebene Technik ist ein Apache Webserver mit dem Modul mod_rewrite. Der Code kann entweder über .htacess oder direkt über die Apache-Konfigurationsdatei eingebunden werden.
Ersetze einfach domain.tld gegen die Domain deiner Website und stoppt_contentdiebe.png gegen den Namen der Grafik, die du Contentdieben unterschieben möchtest.



RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?domain.tld [NC]
RewriteCond %{REQUEST_FILENAME} !stoppt_contentdiebe.png$
RewriteRule .*\.(gif|jpg|png)$ http://domain.tld/images/stoppt_contentdiebe.png [R]

Erklärung zum Script

Zunächst prüfen wir anhand der Direktive filesmatch die Dateiendung gegen einen einfachen regulären Ausdrucks:

Damit erfassen wir alle aufgerufenen Dateien, die die Dateiendung .gif, .jpg oder .png tragen. Selbstverständlich ließe sich der Ausdruck um viele weitere Dateiendungen erweitern, deren direkte Verlinkung wir unterbinden möchten.

Im nächsten Schritt schalten wir die RewriteEngine an. Die RewriteEngine erlaubt es uns mittels RewriteCond verschiedene Parameter des HTTP-Request gegen reguläre Ausdrücke zu prüfen und bei Entsprechung die aufgerufene URL zu manipulieren.

Grundsätzlich müssen wir überprüfen, von welcher Domain aus das Bild verlinkt wurde. Dazu lesen wir den Parameter HTTP_REFERER aus. HTTP_REFERER gibt den Referrer, also die auf einen Link verweisende Domain an.

Getreu dem Motto „Was nicht erlaubt ist, ist verboten“ können wir zwei Bedingungen für ein legitimes Verlinken der Fotos formulieren.

  1. Wenn kein Referrer angegeben ist. Das ist der Fall, wenn beispielsweise durch einen Proxy gelöscht oder die URL direkt aufgerufen wurde.
  2. Wenn der Referrer unserer eigenen Domain entspricht.

Wir können demnach folgende Bedienungen formulieren:

Der Referrer ist leer:

RewriteCond %{HTTP_REFERER} !^$

Der Referrer entspricht unserer eigenen Domain, wobei domain.tld gegen die Domain deiner Website zu ersetzen ist:

RewriteCond %{HTTP_REFERER} !^http://(www\.)?domain.tld [NC]

Damit die RewriteEngine sich nicht in einer endlosen Schleife verfängt, die letztlich mit einem Internal-Server-Error quittiert würde, müssen wir für das dem Trafficdieben unterzuschiebende Bild eine Ausnahme formulieren:

RewriteCond %{REQUEST_FILENAME} !stoppt_contentdiebe.png$

Sind alle Bedingungen erfüllt, greift folgende Regel, mit der wir alle fremdverlinkten Bilder gegen unseren Hinweis ersetzen.

RewriteRule .*\.(gif|jpg|png)$ http://domain.tld/stoppt_contentdiebe.png [R]

bye bye mod_php

Ich habe meine PHP-Apache-Installationen von mod_php auf php_cgi umgestellt. Anlass zu diesem Schritt gab mir, dass ich keine befriedigende Lösung gefunden habe, um beim Schreibzugriff auf Dateien mit PHP Berechtigungskonflikte zwischen Apache und dem User, dem die Dateien eigentlich gehören sollten, auszulösen. Auch war mir schon lange ein Dorn im Auge, dass mod_php nicht mit Threads umgehen kann und dazu zwingt zum ineffizienten Prefork-Modus zurückzukehren. Damit fällt eine wesentliche Verbesserung von Apache2 gegenüber 1.3 weg.
Und nicht zuletzt erscheint es mir in Hinblick auf die Serversicherheit keine gute Idee zu sein PHP mit den weitreichenden Befugnissen des Apache laufen zu lassen – zumal Restriktionen wie open_basedir leicht umgangen werden können.

PHP als FastCGI einzubinden stellt zwar einen etwas höheren Konfigurationsaufwand gegenüber mod_php dar, der jedoch mit Lösung der oben genannten Probleme belohnt wird.

Sobald ich mal wieder ein Quentchen mehr Zeit finde, werde ich ein Mini-Tuorial für Debian 4 an dieser Stelle veröffentlichen. Momentan bin ich noch damit befasst den Geschwindigkeitsunterschied zwischen mod_php und der FastCGI-Variante zu messen.