Archive for the ‘PHP’ Category
XSS-Angriffe erschweren mit CSP, der neuen Idee von Mozilla/Firefox
Die Entwickler bei Mozilla haben hart gearbeitet und sich eine gute Strategie ausgedacht, wie man in Zukunft Cross-Site-Scripting (XSS) erschweren kann (Achtung: unterbinden wird man es (noch) nicht können!). Viele Browserhersteller loben die Firefox-Entwickler dafür und werden die Funktionalität auch einbauen, um das Web ein wenig sicherer zu machen.
XSS ist im Grunde das böse Einfügen von externem Javascript-Code, um im Kontext einer Webseite schädliche Funktionen aufzurufen. XSS-Angriffe haben in den letzten Jahren massiv zugenommen und sind mittlerweile auf Platz 1 der Hitliste aller Internet-Angriffe. Ein einfaches Beispiel ist das folgende:
Nehmen wir an, wir haben ein Gästebuch (oder ein Blog, einen Chat oder irgendeinen anderen Web 2.0 Dienst erstellt, wo User eigenen Content beisteuern können) programmiert, und wir haben bei der Programmierung nicht aufgepasst. Nehmen wir an, wir hätten auf Serverseite bei irgendeinem Formular-Script das Entschärfen der POST-Variablen vergessen, sodass alles, was ein User im Formular eingibt, später auf der Seite von anderen Usern gelesen werden kann.
Kostenlos zur PHP World Kongress in München!
Ich habe heute eine Email erhalten von webmasterpro.de. Dort läuft aktuell eine Verlosung, bei der man ein Ticket für den PHP World Kongress 2009 in München gewinnen kann. Normalerweise kostet das Ticket 890 €!
Wer also am 24./25. November 2009 (das ist in genau einer Woche) zum Kongress möchte, muss nur unter dem Artikel einen Kommentar hinterlassen.
Tolle Aktion wie ich finde, und ich hoffe, dass ich gewinne 😉
Fährt jemand von euch hin?
Bug in PHP 5.3.0’s mail() Funktion
[Edit: Der Bug wurde mit 5.3.2 behoben, siehe Changelog http://www.php.net/ChangeLog-5.php#5.3.2: Fixed bug #50907 (X-PHP-Originating-Script adding two new lines in *NIX). (Ilia)]
Vielleicht hat noch jemand von euch das Problem. Ziel war einfach nur, eine kleine Mail von meinem Mac OS X aus PHP heraus zu versenden. Dazu ist hier PHP 5.3.0 installiert, ebenso wie ein Apache und ein Postfix.
Das Script sieht unspektakulär aus:
$headers = 'From: source@mail.de' . "\n" . 'To: target@mail.de' . "\n" . 'Reply-To: source@mail.de' . "\n" . 'X-Mailer: PHP/' . phpversion(); mail('target@mail.de', 'testmail!', $message, $headers, '-fsource@mail.de');
In der php.ini ist folgendes eingestellt:
sendmail_path = /usr/sbin/sendmail -t -i
Das Problem ist dabei, dass die Emails nicht korrekt ankommen. Alle Header, die ich oben angegeben habe, stehen im Body der Email. Es gibt also ein Umbruchproblem, irgendwo ist einer zuviel.
Return-Path: <source@mail.de> Delivery-Date: Tue, 03 Nov 2009 14:39:05 +0100 Received: from server.de (server.de [111.111.17.10]) by mx.server.de with ESMTP id 0LxhS3-1M6JqE0zvv-016hU3 for source@mail.de; Tue, 03 Nov 2009 14:39:05 +0100 Received: from ip-18-.provider.de (ip-18-.provider.de [222.222.248.46]) by m.server.de with ESMTP id 0LjM2Z-1MTKv00Dgl-00d0Vo; Tue, 03 Nov 2009 14:39:05 +0100 Received: by ip-18-.provider.de (Postfix, from userid 1) id CF7181196C0; Tue, 03 Nov 2009 14:39:04 +0100 (CET) To: target@mail.de Subject: some subject X-PHP-Originating-Script: 501:ErrorController.php Message-Id: <0LjM2Z-1MTKffffgl-00d0Vo@m.server.de> Date: Tue, 03 Nov 2009 14:39:05 +0100 X-Provags-ID: V01U2FsdGVrf1+XTUgdYEhFFTVVw58w3JV/CwkzzZnpRBZbnSR Rtupv2Jro7gRSvDH8j3QVDjBuBuAra893YNAvSVu/TgVETcVIT Y+uvNPgthhI6VXtHYzoCA== X-PhishingScore: 0 tests= X-SpamScore: 2.9 tests= TVD_SPACE_RATIO Envelope-To: source@mail.de From: source@mail.de To: target@mail.de Reply-To: source@mail.de X-Mailer: PHP/5.3.0 Message-Id: <20091029555904.CF7181196C0@ip-18-.provider.de> Date: Tue, 03 Nov 2009 14:39:04 +0100 (CET) message here
Nach etwas rumprobieren, Suchmaschinen bedienen und genauerem Hingucken fällt einem das Problem auf:
PHP ergänzt die Header um einen Eintrag „X-PHP-Originating-Script“. Darin wird der Name des PHP-Scripts festgehalten, welches den mail()-Aufruf gemacht hat. Besonders interessant falls man sich einen fiesen Form-Mailer oder sowas eingefangen hat, und ihn nicht findet. Oder man hat andere Kunden mit ihren Projekten auf seinem Server, die Unfug treiben.
Dieser Header wird von PHP 5.3.0 mit einem „\r\n“ abgeschlossen, und danach folgen die anderen Header.
Da wir hier allerdings unter Mac OS X sind (sprich FreeBSD), wäre ein „\n“ besser. Das betriftt auch Linux etc.
Lösung des Problem ist also: Deaktivieren dieses Zusatzheaders in der php.ini:
mail.add_x_header = Off
Diese Option ist erst seit PHP 5.3.0 verfügbar. In meiner PHP-Version, die hier installiert ist, war das nämlich auf „On“ geschaltet. Im CVS von PHP ist der Bug berichtigt, aber eine 5.3.1 ist aktuell noch nicht released. Hier der Bug-Report, der damit zu tun hat.
Weitere Forenbeiträge zu dem Thema bei Nabble oder auf der Postfixbuch-Mailingliste.
Mein Pagerank
So langsam scheint Google zu merken, dass mein Blog wichtig ist! 😉
Am 17.09. war ich noch auf Platz 149 zu finden, wenn man nach „php blog“ sucht.
26.09. Platz 95
29.09. Platz 52.
06.10. Platz 46
02.11. Platz 48
Ich bin mir noch nicht ganz sicher, warum das gerade stagniert.
Aber es gibt einen Grund zu feiern: Mein Pagerank ist am vergangenen Wochenende von 0 auf 2 gestiegen! Yeah!
Mein gesetztes Ziel sind die Top 10 beim Suchbegriff „php blog“. Ich nehme Tipps immer gern entgegen, wie ich das schaffen kann. Es gibt nämlich viele andere gute PHP-Blogs, und an denen vorbeizuziehen wird nicht einfach. Außerdem sind einige Verzeichnisdienst- und Katalog-Einträge vor meiner eigentlichen Website, was ich gern auch noch beheben würde. Mal sehen.
Der beste Tipp ist wahrscheinlich, mehr gute Artikel zu schreiben. Daran arbeite ich *Schweiss von der Stirn wisch*.
Hier gibt es übrigens Informationen über den Google Pagerank und wann genau die Updates stattfinden. Ich bin ja sehr gespannt ob der Pagerank Ende des Jahres abgeschafft wird, die Diskussion läuft ja gerade (mal wieder).
Asynchron Aufgaben erledigen (lassen)
Was könnte der Autor damit meinen, werdet ihr euch fragen. Naja, das ist schnell erklärt: hier und da hat man mal kleine Aufgaben, die evtl. etwas länger dauern, von dessen Ergebnis der User aber nicht wissen muss. Warum also soll man damit seine PHP-Scripte ausbremsen, und den User warten lassen? Ihn interessiert das Ergebnis ja (erstmal) nicht.
Beispiel: Nehmen wir an, das Versenden eine Informations-Email würde 1 Sekunde dauern (wenn man über einen externen SMTP versendet und nicht über den lokalen, kann das sogar sein). Dann bemerkt der User auf der Webseite eine Verzögerung, die Seite wird langsam.
Es gibt sicherlich noch bessere Beispiele, wie z.B. das Berechnen eines Vorschaubildes. Der User lädt ein Bild hoch (Avatar), und wir brauchen davon eine verkleinerte Version. Wenn dieser Algorithmus nun langsam wäre (was er im Normalfall nicht ist), würde der User vor seinem Bildschirm Däumchen drehen.
Für all solche Aufgaben (ihr findet sicherlich bessere) ist es sinnvoller, diese Aufgaben asynchron erledigen zu lassen. Da gibt es mindestens 2 Möglichkeiten:
- Man trägt die Aufgabe in eine Task-Tabelle in der Datenbank ein, und lässt ein weiteres Script (Cronjob?) diese Task-Liste abarbeiten.
- Man lässt einen Kindprozess diese Arbeit erledigen, welcher geforkt wird, und non-blocking ist
In beiden Fällen bekommt der User direkt die nächste Seite zu sehen und kann weiterarbeiten, der asynchrone Prozess kann aber erst einige Sekunden/Minuten später fertig sein.
Wie setzt man das nun um? Ich glaube, die erste Möglichkeit sollte jedem von euch bekannt sein, da es keine Schwierigkeit ist, eine neue Zeile in einer Datenbank-Tabelle einzufügen, und auch ein Script, das periodisch diese Zeilen liest und abarbeitet, sollte kein Hexenwerk sein.
Die zweite Möglichkeit haben wahrscheinlich deutlich weniger Leute genutzt. Ich finde sie auch ehrlich gesagt unschöner, aber möchte sie trotzdem vorstellen (da sie schneller umzusetzen ist, und häufig auch zum Ziel führt). Als erstes fällt einem da vielleicht der system() Aufruf ein, mit dem man einen weiteren Prozess starten kann. Das Problem daran ist, dass er blocking ist, sprich der nächste Befehl in PHP erst ausgeführt wird nachdem der System-Aufruf beendet ist. Genau das wollen wir ja nicht. Aber unter jedem Betriebssystem gibt es da Möglichkeiten, den Prozess in den Hintergrund zu schieben. Der system() Aufruf ist dann sofort beendet und PHP läuft weiter, parallel läuft ein weiterer Prozess mit der Aufgabe.
function execInBackground($cmd) { if (substr(php_uname(), 0, 7) == "Windows") { pclose(popen("start /B ". $cmd, "r")); } else { system($cmd . " > /dev/null &"); } }
In Maugrim The Reaper’s Blog gibt es eine sehr ausführliche Serie zu dem Thema, mit vielen weiteren Beispielen und Code. Auf jeden Fall lesenswert.
Eine andere interessante Möglichkeit ist Gearman.
http://toys.lerdorf.com/archives/51-Playing-with-Gearman.html
Wenn man etwas andere Voraussetzung hat, könnten die curl_multi_* Funktionen interessant sein. Diese kann man nutzen, wenn man viele Dinge zu erledigen hat, aber auf die Ergebnisse warten muß (weil man sie dem User anzeigen muss). Man möchte also nicht asynchron, sondern simultan arbeiten. Das ganze ist in einem Blogartikel zum Thema „Simultaneuos HTTP requests in PHP with cURL„ super beschrieben.