Gestern bin ich auf PHPIDS gestoßen und bin ziemlich begeistert. Durch PHP IDS (IDS steht für Intrusion Detection System) lässt sich die Sicherheit einer PHP Webanwendung mit wenig Aufwand stark erhöhen. Das System erkennt anhand diverser Filterregeln ob eine Eingabe potenziell schadhaften Code (z.B. für eine XSS-Attacke) enthält und demnach gefiltert werden sollte.
Das Schöne an PHPIDS: Gefiltert wird der gesamte Input der in eine Anwendung hineingeht, indem nicht nur einzelne Eingabefelder, sondern die gesamten superglobalen Variablen überprüft werden. So kann PHPIDS auch prima nachträglich in eine bestehende Applikation integriert werden.
Da PHPIDS außerdem in PHP5 geschrieben, und übersichtlich verpackt wurde, ist es relativ einfach die Bibliothek mit einer Applikation die auf dem Zend Framework basiert, zu kombinieren. In den folgenden, kurzen Snippets sollte deutlich werden, wie das ganze funktioniert.
1. PHPIDS Bibliothek hinzufügen
Zunächst muss PHPIDS in das bestehende Projekt kopiert werden. Dazu sollte man eine aktuelle Kopie von PHPIDS herunterladen und den “lib”-Ordner in den “library”-Ordner des ZF-Projekts kopieren. Schön: PHPIDS folgt den PEAR-Naming-Konventionen, so dass das Autoloading des ZF auch hier prima funktioniert und kein require() eingesetzt werden muss.
2. Wir erzeugen das IDS-Plugin
PHPIDS sollte definitiv als Plugin eingebunden werden. So erfolgt die Integration an einer zentralen Stelle und das Plugin kann sogar für andere Projekte wiederverwendet werden. In unserem Beispiel halten wir eigene Daten in einer “Custom”-Bilbiothek, die parallel zur ZF-Bibliothek im “library”-Ordner gehalten wird. Hier erzeugen wir also im Ordner “library/Custom/Controller/Plugins/” die Klasse “IDS” in der Datei “IDS.php”.
<?php
class Custom_Controller_Plugin_IDS extends Zend_Controller_Plugin_Abstract
{
const IMPACT_THRESHOLD = 20;
private $config = null;
public function __construct(Zend_Config_Ini $config)
{
$this->config = $config;
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$input = array(
'REQUEST' => $_REQUEST,
'GET' => $_GET,
'POST' => $_POST,
'COOKIE' => $_COOKIE
);
$init = IDS_Init::init();
$init->config = $this->config->toArray();
// run the ids monitor
$ids = new IDS_Monitor($input, $init);
$result = $ids->run();
// analyze the result
if (!$result->isEmpty()) {
$impact = $result->getImpact();
// log the event
$compositeLog = new IDS_Log_Composite();
$compositeLog->addLogger(IDS_Log_File::getInstance($init));
$compositeLog->execute($result);
// for high impact, we redirect to error page
if($impact >= self::IMPACT_THRESHOLD) {
throw new Custom_Exception_IntrusionDetection();
}
}
}
}
3. Plugin aktivieren
Das Plugin erwartet bei der Erzeugung eine Instanz von Zend_Config_Ini als Konfiguration für PHPIDS. Diese Konfiguration erstellen wir in der Bootstrap (Bootstrap.php), wo auch das Plugin initialisiert und der Anwendung hinzugefügt wird.
protected function _initPlugins()
{
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Custom_Controller_Plugin_IDS(new Zend_Config_Ini('/pfad/zum/config/verzeichnis/ids.ini', APPLICATION_ENV)));
}
Nun ist das Plugin initialisiert und wird bereits bei jedem Aufruf geladen. Das Verhalten unseres Intrusion Detection Systems können wir jetzt noch in der Datei “ids.ini” festlegen:
4. IDS konfigurieren
[development] General.filter_type = xml General.base_path = /foo/bar/library/IDS/ General.use_base_path = false General.filter_path = /foo/bar/library/IDS/default_filter.xml General.tmp_path = /foo/bar/tmp General.scan_keys = false General.HTML_Purifier_Path = vendors/htmlpurifier/HTMLPurifier.auto.php General.HTML_Purifier_Cache = vendors/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer General.html[] = POST.__wysiwyg General.json[] = POST.__jsondata General.exceptions[] = GET.__utmz General.exceptions[] = GET.__utmc General.min_php_version = 5.1.6 Logging.path = /foo/bar/logs/ids.log Caching.caching = file Caching.expiration_time = 600 Caching.path = /foo/bar/tmp/default_filter.cache [staging : development] [production : staging]
Die Details der Konfiguration können in der Datei /IDS/Config/Config.ini.php nachgelesen werden
Damit sollte unser Intrusion Detection System fertig in unser ZF-Projekt eingebunden sein.
Wir können mittels unserer eigenen Konfigurationsdatei das Verhalten für verschiedene Umgebungen anpassen, so wie wir das von Zend_Config gewohnt sind.
Natürlich muss es nicht dabei bleiben bei einer schadhaften Eingabe nur eine Exception zu werfen. stattdessen könnten wir den Benutzer auch auf eine Fehlerseite umleiten oder die Applikation komplett stoppen. Dazu sollte dann die Zeile
throw new Custom_Exception_IntrusionDetection();
in unserem Plugin mit der gewünschten Behandlung ersetzt werden.
Gerne könnt Ihr eure Fragen und Anmerkungen in den Kommentaren hinterlassen
Ähnliche Artikel:
Hi,
danke für den Hinweis (auch wenns schon ne Weile her ist). Hat mir gut geholfen, musste allerdings ein paar Sachen ändern, dass es geklappt hat. Nun läuft es aber, sogar mit exception im preDispatch und landet direkt aufm ErrorController bei einem zu hohen ImpactLevel.
Gruß
Domi
Domi
29 Aug 11 at 11:18