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

HTML-Eingaben in eigenen Joomla Komponenten gestatten

Die Methode JRequest::get filtert per default HTML- und PHP-Code aus den Request. Möchte man beispielsweise ein HTML-Eingabefeld in der eigenen Komponente nutzen, lässt sich dies über die MethodeJRequest::getVar mit dem Parameter JREQUEST_ALLOWRAW erreichen.

Zum Beispiel so:

$description = JRequest::getVar('description','','post','string', JREQUEST_ALLOWRAW);

TurboDbAdmin, die Web 2.0 Alternative zu phpMyAdmin

TruboDbAdmin versprich eine interessante Alternative zu phpMyAdmin zu werden. Zwar kann TurboDbAdmin noch nicht mit dem Funktionsumfang von phpMyAdmin gleichziehen, jedoch bietet es dank extensiven Einsatz von AJAX-Technologie einen wesentlich höheren Komfort.

suPHP

Interessante Alternative zu PHP als CGI

Unable to create temporary directory

Wenn Windowsuser PHP lernen und dafür gleich einen Rootserver anmieten, muss das in einer Katastrophe enden.

Ultimate Tag Warrior: URL-Rewriting

UTW ist ein tolles Plugin für WordPress, um Postings mit Tags zu versehen und Tagclouds als Navigationsmittel zu erzeugen. Dabei ist sogar eine Option vorgesehen, mit der sich schöne URL in Form von BASEURL/tag/tag erzeugen lassen. Bislang blieb diese Funktionalität meiner WordPress Installation jedoch versagt. Zwar konnte ich die Option aktivieren, die Tag Links verweisen auch auf URLs wie BASEURL/tag/linux, aber WordPress vermochte sie nicht auf den eigentliche URL BASEURL/index.php?tag=linux umzuschreiben.
Des Rätsels Lösung fand ich während ich mich in das Rewriting von WordPress einarbeitete.
Wenn Permalinks (so der von WordPress gewählte Name für scheinbar statische, saubere URLs) aktiviert werden, schreibt WordPress eine .htaccess mit folgendem Inhalt (gekürzt):

CODE:
  1. RewriteEngine On
  2. RewriteBase /
  3. RewriteCond %{REQUEST_FILENAME} !-f
  4. RewriteCond %{REQUEST_FILENAME} !-d
  5. RewriteRule . /index.php [L]

Sofern es sich bei der angeforderten Ressource nicht um ein tatsächlich auf dem Webspace vorhandenes Verzeichnis oder File handelt, wird die Anfrage auf die index.php umgeschrieben.
Hier übernimmt dann die Klasse WP_Rewrite, die mit eigenen Regelwerk die sonst an mod_rewrite delegierte Aufgabe übernimmt statische URLs in dynamische umzusetzen. Geparster PHP-Code ist zwar nicht ansatzweise so effizient wie das in C implementiere und bewährte mod_rewrite, bringt aber den entscheidenden Vorteil einer durch Plugins nutzbaren API mit sich. Von der macht der Entwickler des Ultimate Tag Warrior auch Gebrauch, indem er in der Funktion ultimate_rewrite_rules (zu finden in der Datei ultimate-tag-warrior-actions.php) ein neues Rewrite-Tag registriert und zwei neue Rewrite-Regeln hinzufügt.

PHP:
  1. $wp_rewrite->add_rewrite_tag('%tag%', '([^/]+)', 'tag=');
  2. // without trailing slash
  3. $rules += $wp_rewrite->generate_rewrite_rules($baseurl . "%tag%");
  4. // with trailing slash
  5. $rules += $wp_rewrite->generate_rewrite_rules($baseurl . "%tag%/");

Soweit so gut, funktioniert nur leider nicht. Ich vermutete, dass die von UTW registrierte Rewrite-Regel mit anderen, zuvor hinterlegten, kollidierte. Darum passte ich versuchsweise den Code dahingehend an, dass die UTW-Rewrite-Regeln vor allen anderen abgearbeitete würden.

PHP:
  1. $wp_rewrite->add_rewrite_tag('%tag%', '([^/]+)', 'tag=');
  2. // without trailing slash
  3. $rules = $wp_rewrite->generate_rewrite_rules($baseurl . "%tag%") + $rules;
  4. // with trailing slash
  5. $rules = $wp_rewrite->generate_rewrite_rules($baseurl . "%tag%/") + $rules;

Und tatsächlich: Nun sind auch saubere URLs mit dem Ultimate Tag Warrior möglich. Alles andere scheint auch zu funktionieren. Jedoch ist das weder eine saubere noch befriedigende Lösung. Ich wüsste gerne, warum und mit welchen Regeln die von UTW registrierten zusammenstoßen. Mir fehlt es momentan allerdings an Zeit und Lust den Code zu debuggen - zumal ich mir nicht sicher bin, ob UTW kaputt ist, WP_Rewrite oder mir nur ein anderes Plugin in die Quere kommt.

Mr Wong codes wrong

Mich erschreckt immer mehr, wie dilletantisch proffessionelle Websites mit hohen Bekanntheitsgrad und Besucherzahl implementiert sind. Heute Morgen zum Beispiel hat der Social-Bookmarking-Dienst Mr Wong einen Totalausfall:

Mr Wong Fehlermeldung

Das kann passieren, auch bei Profis. Die Frage ist nur, wie man mit solchen Fehlern umgeht. PHP-Fehlermeldungen in einem Produktivsystem über den Browser auszugeben, ist eine schlechte Idee. Oftmals geben diese Fehlermeldungen Auskunft über Implementierungsdetails aus, die einem potentiellen Angreifer Sicherheitslücken offenbaren können. Normale Benutzer können mit Fehlermeldungen des PHP-Interpreters gar nichts anfangen, darum sollten sie in verständlichen Worten darüber informiert werden, warum der Dienst momentan nicht funktioniert. Etwa in der Form von: "Unsere Datenbank ist ausgefallen. Unser Administrator wurde informiert. In Kürze wird der Dienst wieder zur Verfügung stehen. Wir bitten den Ausfall zu entschuldigen." Und bevor solche Meldungen überhaupt ausgegeben werden, sollte der Administrator benachrichtigt werden. Mit Exceptions wäre das alles kein Problem:

PHP:
  1. try {
  2.     // Hier kann was schiefgehen!
  3. } catch (Exception $fehler)
  4. {
  5.     // Gib was sinnvolles aus, informiere den Sysadmin, don't panic!
  6. }

Um keinen Code duplizieren zu müssen und Exceptions gezielter behandeln zu können, lassen sich in PHP5 sogar eigene Exceptions implementieren. Außerdem bringt die PHP-SPL vordefinierte Exceptionklassen mit. Doch dazu wann anders mehr.

Ironischerweise hat die Agentur hinter Mr Wong vor kurzem eine Stelle für PHP-Entwickler ausgeschrieben. ;)

Professionelle Softwareentwicklung mit PHP5

Professionelle Softwareentwicklung mit PHP5Der Code der meisten in PHP implementierten Anwendungen ist schlecht. Schlecht bedeutet nicht etwa, dass er nicht funktionieren würde. Aber er ist schlecht zu warten, kaum wiederverwendbar und anfällig für Fehler. Die Objektorientierung bietet Paradigmen und Patterns, die konsequent angewandt zu guten Code führen, doch bis zu Version 4 wurde ein objektorientierter Ansatz in PHP gar nicht oder nur nominell unterstützt. Seit Version 5 beginnt die populäre Scriptsprache sich zu professionalisieren, allerdings können nur wenige Entwicklern einen Nutzen daraus ziehen. Denn viele, wenn nicht die meisten PHP-Programmierer lernten PHP als erste Programmiersprache und sind nicht mit professionellen Entwurfs- und Implementierungstechniken vertraut. Abhilfe schafft das Buch Professionelle Softwareentwicklung mit PHP5 von Sebastian Bergmann: Der Autor richtet sich an den fortgeschrittenen PHP-Entwickler und erläutert ihm Objektorientierung, Entwurfsmuster und Modellierung mit UML aufs Wesentliche reduziert, abstrakt und doch praxisnah. Wer professionell in PHP entwickeln möchte, meistert mit diesem Buch den bequemen Einstieg.

Die erste Auflage des Buchs stellt der Autor auf seiner Website als HTML-Version kostenlos zur Verfügung.

Das PHP-Manual lügt

Gehen wir von folgendem Codeschnippsel aus:

PHP:
  1. $a = 'a';
  2. $a++;
  3. echo $a;
  4.  
  5. $b = 'a';
  6. $b = $b + 1;
  7. echo $b;

Wer vermag ohne Ausprobieren zu sagen, welchen Wert $a und welchen Wert $b hat?
Wäre PHP eine konsistente Programmiersprache, sollten $a und $b den gleiche Wert haben. Gemäß der Logik von PHP ist jedoch a == 'b' und b == 1.
Eine Sprache, die zu solchen Überraschungen führt, wird tatsächlich als besonders einsteigerfreundlich gehandelt. Als Argument für PHP wird neben der flachen Lernkurve immer wieder auf die hervorragende Dokumentation verwiesen. Wie gut kann wohl ein Manual sein, dass zu oben genannten Phänomen folgendes verklärt?

PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's. For example, in Perl 'Z'+1 turns into 'AA', while in C 'Z'+1 turns into '[' ( ord('Z') == 90, ord('[') == 91 ). Note that character variables can be incremented but not decremented and even so only plain ASCII characters (a-z and A-Z) are supported.

Dass 'Z'+1 'AA' ergeben soll, halte ich für eine Lüge.

PHP nervt

Gibt es eigentlich irgendeinen logischen Grund, warum es keine einheitliche Namensgebung für PHP-Funktionen gibt? Jedes mal sitze ich vor der Tastatur und überlege, wie denn nun der Funktionsname geschrieben wird. Heißt es nun stripcslashes oder strip_cslashes? Und wenn es stripcslashes, warum heißt es dann strip_tags und nicht striptages? Das gleiche Problem bei strtolower und bin2hex. Klar: PHP ist eine gewachsene Sprache und wurde von Version zu Version um Funktionalität erweitert; da lassen sich Innkonsistenzen nicht immer vermeiden. Aber was hindert das Entwicklerteam daran die Namensgebung zu vereinheitlichen, indem sie Synonyme zulassen und von der Norm abweichenden Funktionsnamen als deprecated kennzeichnen?

PHP unterstützt mittlerweile eine sinnvolle Fehlerbehandlung durch Exceptions - dumm nur, dass kritische Funktionen wie file() keine Exception werfen.

PHP6 lässt zumindest hoffen, dass in kommenden Versionen die Sprache endlich von den Altlasten befreit werden kann. Denn es ist zwar schön, dass mensch seit PHP5 fortgeschrittene objektorientierte Implementierungstechniken anwenden kann, aber es macht eben wenig Spaß, diese auf Relikten der strukturierten Programmierung aufsetzen.