PHPIDS im Praxistest

Nachdem ich in letzter Zeit einiges über das Intrusion-Detection-System PHPIDS gelesen habe, habe ich es nun selbst einmal getestet. Hier meine bisherigen Erfahrungen:

Testumgebung Für den Test habe ich Projekt genutzt welches sich derzeit noch in der Entwicklung befindet. Das Projekt liegt lokal auf einem Thinkpad T42 (1,7Ghz und 2GB Ram) in einer XAMPP-Umgebung mit XDEBUG.

Installation / Integration Zunächst müssen die PHPIDS-Dateien (es reicht das Verzeichnis "lib/IDS") auf den Server geladen werden. Das Verzeichnis "IDS/tmp" benötigt Schreibrechte falls man dort Log- oder Cache-Files ablegen möchte. Anschließend müssen in der Datei Config.ini (IDS/Config) ein paar Einstellungen angepasst werden. Die Datei ist selbsterklärend, ich habe jedoch nur die Pfade angepasst da ich für meinen Test auf Logging oder Caching in einer Datenbank verzichtet habe.

Die Integration von PHPIDS in ein bestehendes Projekt hängt natürlich sehr stark vom Projekt selbst ab. In meinem Testfall werden sämtliche Anfragen per mod_rewrite auf die Datei index.php umgeleitet. Dort wird unter anderem eine Klasse security instanziert welche verschiedene Methoden zur Input-Validierung enthält. Eine dieser Methoden (validate_request) wird bei jedem Aufruf des Projektes ausgeführt und ist somit der ideale Ansatzpunkt für PHPIDS. Das ist der hier relevante Teil der security-Klasse:


// include-path auf den Ordner mit IDS setzen:
ini_set('include_path', '/path/to/libs');
// IDS einbinden:
require_once 'IDS/Init.php';
// Array mit möglichen User-Inputs bilden:
$request = array(
    'REQUEST' => $GLOBALS['_REQUEST'],
    'GET' => $GLOBALS['_GET'],
    'POST' => $GLOBALS['_POST'],
    'COOKIE' => $GLOBALS['_COOKIE']
);
// IDS initialisieren:
$init = IDS_Init::init('/path/to/libs/IDS/Config/Config.ini');
// Caching ausschalten:
$init->config['Caching']['caching'] = 'none';
// Request-Array analysieren:
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();
// Impact abfragen und ggf. reagieren:
if($result->getImpact() > 1)
{
    die('Hacking attempt detected. IP logged.');
}
// include-path auf seinen ursprünglichen Wert zurücksetzten:
ini_restore('include_path');

Was hier passiert ist schnell erklärt: Es wird ein Array gebildet welches alle Variablen enthält die vom Benutzer beeinflusst werden können, etwa durch Formulareingaben oder Ähnliches. Der Inhalt dieses Arrays wird nun von PHPIDS auf mögliche Angriffsversuche untersucht. Mögliche Angriffe wären z.B. XSS oder SQL-Injection Attacken. Erkannte Angriffe werden von PHPIDS bewertet. Je "gefährlicher" oder "bedrohlicher" ein Angriff ist, desto höher ist der Impact-Wert. Im obigen Beispiel wird das Script sofort beendet sobald der Wert größer als 1 ist.

Performance Aufgrund vieler regulärer Ausdrücke u.Ä. ist PHPIDS sicherlich nicht extrem Performant, aber es ist auch nicht extrem langsam. In meinen Test gab es nur einen Angriff der PHPIDS quasi in die Knie gezwungen hat. (Genaueres weiter unten) Ob man dieses Tool nun auf einer High-Performance Webseite einsetzen kann ist schwer zu sagen. Hier kommt es sicherlich auf die Server, das Caching und viele andere Dinge an. Hier jedoch ein kurzer Vergleich der Methode validate_request mit und ohne PHPIDS (eingebunden wie oben beschrieben). Es handelt sich um einen einfachen Aufruf der Seite ohne dass irgendwelche Angriffe versucht werden.

Bei Standard-XSS-Angriffsversuchen wie man sie z.B. hier findet gehen die Zeiten leicht nach oben, bleiben aber immer im Rahmen. Hier das Ergebnis bei einem GET-Parameter mit folgendem Imhalt:

<img SRC="javascript:alert('XSS');">

Einen Fall konnte ich jedoch finden, bei dem PHPIDS stark einbricht. Es handelt sich um einen SQL-Injection Angriff der kürzlich verwendet wurde um Javascript auf vielen Webseiten einzuschleusen. (Artikel bei heise.de) Wird der String aus diesem Angriff per GET-Parameter übergeben steigt die Prozessorlast extrem an und das Script braucht lange für die Ausführung. Verantwortlich dafür sind 164 Aufrufe der Funktion preg_match die extrem lange brauchen. In meinem Test waren es über 4000ms.

Fazit PHPIDS ist ein sehr nützliches Hilfsmittel um viele Angriffe auf Webprojekte zu erkennen. Die Installation ist kinderleicht und auch bei der Integration in ein bestehendes Projekt sollte es keine größeren Probleme geben. Auf zwei Dinge möchte ich jedoch Hinweisen:

  1. PHPIDS ist ein System zur Erkennung von Angriffen, es ist nicht dazu da sie zu verhindern oder zu blockieren. Diese Aufgabe muss ein Entwickler selbst übernehmen.
  2. PHPIDS verwendet teilweise viele reguläre Ausdrücke welche resourcenhungrig sind. Bei High-Traffic Projekten sollte man deshalb ein Auge auf die Serverlast haben und sich das PHPIDS-Caching genauer anschauen.