10 Jul 2011, 16:56

Memcache Sessions may cause zend_mm_head corrupted in PHP5

PHP5 (5.3.3 in this case) may break in very supprising ways if the Memcached configured as a session handler goes awry.

In my case there was a webserver (Apache2 + mod_php5) w/ two memcached configured as session handler. One of those memcached got stuck and didn’t properly reply to request. This shouldn’t happen but whats even worse was that PHP5 just “died” with the following error in the syslog:

vs-www-s01 suhosin[32504]: ALERT - zend_mm_head corrupted at 0x7fc2f41a2090 (attacker ‘10.1.2.3’, file ‘/var/www/index.php’)
This resulted in empty pages delivered to the browser.

After fixing the memcached everything was fine again.

28 Jan 2008, 17:41

PHP5.2 bringt inkonsistente include_path Fehler

Es sieht ganz so aus als ob PHP5.2.x einen komischen Bug in Verbindung mit Apache VHosts und dort gesetzten include_paths hat.

Sobald man in einem VHost den include_path ändert funktioniert ini_set in allen Vhosts nicht mehr. Um das ganze noch ein wenig spannender zu machen tritt der Bug nicht immer auf, d.h. er ist extrem schwer zu debuggen.

Toll.

Update: Die Lösung war keine Include_Paths in den Vhosts zu setzen, da das PHP5 Modul damit Probleme hat.

22 Jan 2008, 10:49

Email Adresse in PHP validieren

if(!pregmatch(“/^[A-Z0-9.%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}$/i”,$email)) { return true; }

Quelle: How to find or validate Email Adress 

15 Jan 2008, 10:18

Scaffoldr 2.0

Wer bei PHP/MySQL Projekten die CRUD Seiten fürs Backend nicht dauernd von Hand bauen will und keine Lust hat sich in ein riesiges Framework einzuarbeiten der sollte sich mal meinen CRUD Code Generator Scaffoldr anschauen.

Das ist ein Template basiertes PHP Script das die CRUD Seiten für eine komplette Datenbank innerhalb weniger Sekunden erstellt. Inkl. differenzierter Behandlung der einzelnen Feld-Datentypen, sortierbaren Spalten sowie “Pageination”.

Ich benutze das oft als Basis für das Administrationsbackend von Webprojekten. Für ein Benutzer-Frontend ist es dagegen weniger geeignet, da weitgehend auf Sicherheitsüberprüfungen verzichtet wird. Daher vorsicht vor SQL-Injection Attacken wenn man nicht vertrauenswürdige Benutzer ran lässt.

13 Dec 2007, 11:47

Eclipse RCP: CorruptedCodeException

Wenn man versucht eine RCP Application mit dem FlexiProvider und dem FhG Codec zu bauen laufen einem zuweilen schon sehr komische Fehler über den Weg.

Interessant wird es wenn die RCP-App. gar nicht mehr startet und CorruptedCodeExecptions schmeißt.

Es gibt ein paar Punkte auf die man achten sollte.

RCP Manifest - Build Screen

In der Build Configuration muss das aktuelle Verzeichnis (.) aufgenommen werden.

RCP Manifest - Dependency Screen

Man sollte, wenn möglich, auf unnötige Plug-ins verzichten.

RCP Manifest - Runtime Screen

Gaaanz wichtig: Alle Pakete das Projekts exportieren und, noch wichtiger, das Verzeichnis “bin/” mit in den Classpath!

Good Luck.

30 Oct 2007, 07:30

PHP/MySQL: Client does not support authentication protocol

Problem: PHP/MySQL kann sich nicht zu einem MySQL-Server verbinden und bricht mit der Fehlermeldung Client does not support authentication protocol ab.

Das passiert wenn die Version der MySQL Laufzeit Bibliothek inkompatibel mit der Version des MySQL-Servers ist, da irgendwann das Format der Passworte geändert wurde.

Wenn man sich dennoch mit einem “alten” Client zum Server verbinden will kann man für diese Benutzer das Passwort auf das alte Format zurücksetzen indem man folgenden Befehl ausführt SET PASSWORD FOR ‘some_user’@‘some_host’ = OLD_PASSWORD(‘newpwd’);.

Weitere Informationen gibts in der MySQL-Dokumentation.

22 Oct 2007, 07:30

Komplexe Datenstrukturen in PHP?

Nachdem ich mir Gedanken über eine Portierung des Spell Checkers von Java nach PHP gemacht habe, ist mir aufgefallen, dass es scheinbar gar keine komplexen Datenstrukturen in PHP gibt.

Natürlich kann man sich das alles selbst bauen, aber eine ordentliche Implementierung von Set, List, Tree & Co. wie in Java scheint es in PHP nicht zu geben.

Das Problem bei der PHP Umsetzung ist im Moment, dass ich ja keine ständig laufende Application sondern einzelne Request habe und daher nicht jedesmal den langwierigen Trainingsprozess durchlaufen kann. Als Alterantive scheint mir eine SQL-Datenbank geeignet, aber bevor das so funktioniert wie ich es mir vorstelle muss ich noch einen Weg finden die Daten dort effektiv abzulegen und aufzufinden. 90.000 SQL-Abfragen pro Suchanfrage sind einfach noch ein bischen zu viel ;)

20 Oct 2007, 08:00

No Spam!

Gestern bin ich durch eine Anzeige auf das Buch “No Spam! Besser vorbeugen als heilen” von Tobias Eggendorfer aufmerksam geworden.

In der Anzeige wurden unter andem die folgenden Punkt angeführt:

  • Woher haben Spammer die Adressen?
  • Grundlegende Vorsichtsmaßnahmen
  • eMail Adressen verstecken
  • Harvester blockieren
  • Absichern von Mailinglisten und Newslettern
Wenn ich das Inhaltsverzeichnis so lese, fage ich mich ernsthaft warum man dieses Thema auf ca. 160 Seiten aufblähen muss, und warum man dazu ein ganzes Buch verfasst. Die angesprochenen Punkt lassen sich eigentlich in ein paar Zeilen zusammenfassen, und genau das werde ich hier versuchen.

Was ist Spam?

Der Begriff Spam stammt aus einem Monty Python Sketch und ist die Umgangssprachliche Bezichnung für UCE/UCB was für “Unsolicited Commercial E-mail” bzw. “Unsolicited Commercial Bulk E-mail” steht. Gemeint sind damit unerwünschte Nachrichten die in großem Umfang an eine Vielzahl von Benutzern verschickt wird. Ein weiteres Merkmal von Spam ist, dass in der Regel keine (bewusste) Anmeldung/Einwilligung zum Empfang desselben erfolgte.

Woher haben Spammer die Adressen?

Wer eine möglichst große Anzahl an Personen im Internet erreichen will, kommt über kurz oder lang vielleicht auf die blöde Idee einfach Massenhaft Mails mit Werbung zu verschicken. Doch woher bekommt man die ganzen Adressen? Dafür gibt es ein paar Möglichkeiten. Der naivste Ansatz ist die Brute-Force Methode, d.h. einfach einen Mailserver kontaktieren und alle möglichen Kombinationen von zulässigen Zeichen als Emfänger auszuprobieren. Dies ist natürlich sehr Zeit- und Resourcen intensiv und führt wahrscheinlich bei den meisten Mailservern dazu, dass der sendende Host komplett ausgesperrt wird.

Ein besserer Ansatz, für den Spammer, ist es im Internet nach echten Adressen zu suchen. Dazu werden, ähnlich wie bei Suchmaschinen, sogenannte Spider bzw. Harvester eingesetzt, die von einer Seite aus starten und dann jedem ausgehnden Link folgen und alle Mail-Adressen, erkennbar an dem “mailto:” Prefix, in einer Datenbank speichern. Hier ist auch gleich der erste Ansatz den Spammern die Tour zu vermiesen: Die eigenen eMails verschleiern. Dazu gibt es mehrere Möglichkeiten, aber dazu später mehr.

Grundlegende Vorsichtsmaßnahmen

Hier lautet die oberste Devise: Datensparsamkeit. Man sollte generell möglichst sparsam mit seinen Daten, in diesem Fall der Mail-Adresse, umgehen. Wenn man jedoch seine Adresse seine eigene Adresse veröffentlichen muss, der sollte sicher Gedanken darüber machen wie er diese für Harvester unbrauchbar macht.

Dafür gibt es verschiedene Möglichkeiten:

  • eMail Adresse verschleiern/verstecken
  • einmal Adressen, d.h. eine Adresse pro Nutzungszweck
  • ablaufende Adressen
Auf die einzelnen Punkte gehe ich gleich nochmal ein.

eMail Adresse verstecken

Wenn man seine Adresse für Menschen zugänglich machen will, oder muss, Stichwort Impressumspflicht, dann sollte man diese entweder durch Ersetzungen unkenntlich machen, z.B. info@gauner.org wird zu into_AT_gauner_DOT_org, wobei es hier auch die Möglichkeit gibt, dass Spammer diese Ersetzungen einfach enttarnen können. Eine weiter Möglichkeit ist es die ganze Adresse, oder einen Teil davon, durch Grafiken zu ersetzen. Eine dritte Möglichkeit ist den “mailto:info@gauner.org” Teil durch eine Javascript Funktion zu ersetzen die beim anklicken die richtige Adresse erzeugt.

Einmal Adressen

Eine gute Möglichkeit die Menge des eingehenden Spams zu steuern und zu kontrollieren woher der Spam kommt ist das verwenden von sog. einmal Adressen. Hierbei legt man für jeden Verwendungszweck, z.B. Registrierung in einem Forum oder Blog, eine eigene Adresse wie z.B. gauner-blog@xy.host.tld an und leitet diese auf seine eigentliche Adresse weiter. Wenn man jetzt einmal Spam erhällt kann man anhand der Empfänger-Adresse einfach feststellen wie der Spammer an die Adresse gekommen ist. Jetzt kann man jederzeit diese Adresse zu löschen und man wird auf diesem Weg keinen Spam mehr erhalten. Der Nachteil hierbei ist, dass man eine ziemlich große Zahl an Weiterleitungen anlegen muss und einen Provider benötigt der dies unterstützt.

Ablaufende Adressen

Es ist auch möglich einfach Adressen zu verwenden aus denen deutlich wird, wann Sie ablaufen. Diese Adressen haben die form Max.Mustermann-expires20071031@gauner.org. Diese Adresse können dann nach belieben Benutzt werden, da man Sie nach einer gewissen Frist, meist wenige Monate, einfach nicht mehr benutzt. Ein Nachteil ist natürlich, dass man diese Adresse dann ggf. an vielen Stellen ändern muss. Mir persönlich wäre dieser Aufwand einfach zu groß.

Harvester blockieren

Um den Spammern das Leben weiterhin schwer zu machen gibt es sog. Honeypot Ansätze, die versuchen Harvester in eine Falle zu locken. Diese Falle ist eine speziell angelegte Webseite mit jeder Menge interner Verweise und künstlich erzeugten, ungültigen eMail-Adressen, die die Ressourcen der Harvester binden und mit unnützen Adressen überfluten soll.

Absichern von Mailinglisten und Newslettern

Zum absichern von Mailinglisten und Newslettern ist es generell sinnvoll entweder die vorhandenen Funktion zur Entfremdung der Mail-Adressen der Nutzer zu verwenden, oder sich selbst Gedanken über eine solche Funktion zu machen. Der, in meinen Augen, beste Ansatz ist die verwendung von Bilder zur Darstellung der Mail-Adressen, bzw. von Teilen davon. Dabei darf man natürlich nicht vergessen, dass der Inhalt der, im Bild dargestellten Zeichenkette, nicht im alt Tag angegen werden sollte. Dies läuft zwar der Barrierefreiheit entgegen, aber das ist wohl einer der Kompromisse die man im Moment eingehen muss.

Fragen?

Ich hoffe, dass ich hiermit einige vorbeugende Schritte zur Spam Vermeidung ein wenig erläutern konnte und falls noch Fragen auftauchen steht natürlich die Kommentar Funtkion jederzeit offen. Da man auch hier nicht von Spam verschont bleibt ist leider das lösen einer kleinen Rechenaufgabe notwendig. Aber zum Thema Kommentar-Spam werde ich ein anderes mal etwas sagen …

18 Sep 2007, 09:35

PHP: Cannot access empty property

Kurztipp: Probleme nach der Migration von PHP4 zu PHP5 (I)

Folgendes Problem tritt nach der Migration von PHP4 zu PHP5 auf:

Fatal error: Cannot access empty property in /www/xyz/abc.php on line xy
Bei mir ist dieses Problem aufgetreten weil sich da ein $ eingschmuggelt hatte wo es nichts zu suchen hatte.

Vorher $this->free_result($this->$query_id);

Nacher $this->free_result($this->query_id);

Wie man sieht genügt es das $-Zeichen zu entfernen.

30 Aug 2007, 11:14

XML Dokumente mit Namespaces in PHP5/SimpleXML verarbeiten

SimpleXML ist was feines. Damit lassen sich XML Dokumente ohne viel Aufwand bearbeiten, leider hat das ganze einen kleinen Haken.

Namespaces! Richtig, SimpleXML kann Namespaces zwar verarbeiten aber dadurch wird die Bedienung etwas verwirrend und leider ist das ganze auch nicht gut Dokumentiert.

Ein kleines Beispiel, gegeben sei folgende XML Datei: <XmlResultSet version=“1.0.0” xmlns=“http://www.gauner.org/api" xmlns:bml=“http://www.bla.net/bml" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://www.gauner.org/api/schema.xsd"> <bml:description>This is an API</bml:description> <bml:name>api</bml:name> <bml:Member> <AnEntry> <bml:name>Blabla</bml:name> </AnEntry> </bml:Member> </XmlResultSet>

So, jetzt mal angenommen ich will auf Xml->bml:Member->AnEntry->Name zugreifen. Ohne Namespaces ist das mit SimpleXML ganz einfach: Xml->Member->AnEntry->Name. Aber das lustige an Namspaces ist, dass die jeweils anderen Namespaces ausgeblendet werden. D.h. SimpleXML sieht alles im Namespace “bml” erstmal nicht.

Ok, dafür gibts eine Lösung: Man kann mit Element->children(‘namespace-url’) explizit auf die Namespaces zugreifen, aber dabei gibt es zwei Fallen. Zum einen muss man unbedingt die URL des Namespaces angeben, nicht etwas den Namen des Namespace, und zum anderen ist es wichtig zu beachten, dass dann eben die anderen Namespaces augeblendet werden, und man ggf. wieder in den Default Namespace (mit ->children(“)) wechseln muss.

Wenn ich jetzt in obigem Beispiel auf <bml:name> Zugreifen will sähe der korrekte Code dann etwa so aus: $xml = new SimpleXMLElement($source); $name = $xml->children(‘http://www.bla.net/bml')->Member->children('')->AnEntry->children('http://www.bla.net/bml')->name;

Siehe dazu auch den Eintrag bei SitePoint.