Facebook
Twitter
Google+
Kommentare
0

Das Problem mit HEAD Requests in PHP

Ich bin gerade auf ein interessantes Verhalten gestoßen das eventuell große Probleme bereiten kann. Wahrscheinlich nur sehr wenige von euch werden das hier wissen, trotzdem ist es sehr interessant und provoziert eventuell Probleme und Sicherheitslücken.

Das hier vorgestellte Verhalten ist wahrscheinlich kein Problem von PHP sondern eventuell vom Webserver, aber ich weiß es nicht genau. Vielleicht kann ja mal jemand mit Tomcat oder nginx dieses Problem nachstellen.

Wir nehmen folgendes Script als Beispiel:

<?php
file_put_contents('/tmp/outp', '1');

echo 'start';
file_put_contents('/tmp/outp', '2', FILE_APPEND);
echo 'ende';

Ich glaube ihr stimmt mir alle zu wenn ich behaupte: Das Script erstellt immer eine Datei mit dem Inhalt “12″. Es kann zum Beispiel nicht passieren dass nur “1″ in der Datei steht.

Falsch gedacht. Ein Client (Browser) kann einen HEAD Request zum Webserver(Apache) schicken, d.h. der Client ist nur an den Header-Informationen der Antwort interessiert. Was tut der Apache? Er startet das PHP Script, und bricht es bei der ersten Ausgabe ab!! Denn dann kann man mit PHP nicht mehr die Header verändern, und der Apache spart CPU etc. und stoppt das PHP-Script.

Was bedeutet das für unser Beispiel-Script? In der Datei /tmp/outp steht plötzlich nur “1″ drin. Man kann sich nun überlegen was das für seine eigene Applikation bedeutet. Man schaue sich dieses Beispiel an:

<?php
session_start();
$_SESSION['admin']=1;

if (!isset($_POST['pass']) || $_POST['pass']!='somepassword') {
    echo '<b>Wrong or empty password.</b><br>';
    $_SESSION['admin']=0;
} else {
    echo 'logged in';
}

Ich hoffe niemand programmiert so, aber ihr sehr das Problem: In der Session wird erstmal ein Flag gesetzt, das bei falschem Passwort wieder zurückgesetzt wird. Normalerweisse funktioniert das super, es sei denn jemand schickt einen HEAD Request wird mit falschem Passwort, dann wird das Script beim echo gestoppt, in der Session ist der Benutzer dann eingeloggt!

Oder stellt euch vor ihr habt ein Script, das eine CSV-Datei erstellt, zum Beispiel so:

<?php

$data = <datenbankabfrage>

foreach ($data as $d) {
    file_put_contents('/tmp/csv.csv', $d['id'] . ';' . $d['name'] . "\n", FILE_APPEND);
    echo ".";
}

Falls jemand das Script mit der Methode HEAD aufruft wird eure CSV-Datei nur eine Zeile enthalten, sprich defekt sein, euer System das von der Vollständigkeit der CSV-Datei ausgeht wird Fehler produzieren.

Was kann man gegen dieses Problem tun? Man rechnet einfach immer damit dass ein Script auch abbrechen kann (wenn der Apache abstürzt, das Netzteil durchbrennt), man nutzt Output-Buffering (ob_start() etc.) oder deaktiviert HEAD-Requests komplett.

Eventuell habt ihr weitere interessante Beispiele was dadurch kaputt gehen kann. Das ist jedenfalls ein Problem über das ich mir so noch nie Gedanken gemacht habe. Das Problem habe ich in diesem PDF gefunden.

flattr this!

Über den Autor

PHP Gangsta

Der zweitgrößte deutsche, eher praxisorientierte PHP-Blog von Michael Kliewe veröffentlicht seit Mitte 2009 Artikel für Fortgeschrittene.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen