Protecting php applications with PHPIDS
PrintIntroduction
PHPIDS (PHP-Intrusion Detection System) is a simple to use, well structured, fast and state-of-the-art security layer for your PHP based web application. The IDS neither strips, sanitizes nor filters any malicious input, it simply recognizes when an attacker tries to break your site and reacts in exactly the way you want it to. Based on a set of approved and heavily tested filter rules any attack is given a numerical impact rating which makes it easy to decide what kind of action should follow the hacking attempt. This could range from simple logging to sending out an emergency mail to the development team, displaying a warning message for the attacker or even ending the user's session
In a nutshell PHPIDS is an advanced intrusion detection system written with performance on a large scale in mind. The basic installation and configuration is pretty straight forward.
Requirements
- PHP 5.1.2 or better
- Apache
- mod_rewrite
Installation
First we need to download the latest stable release at http://php-ids.org/downloads/ and decompress it. Please note that you do not want public access to the phpids directory. I recommend that you place it above your document root.
If you are on a shared host and cannot place it above the document root the following rewrite will prevent unwanted access.
RewriteEngine On RewriteCond %{REQUEST_URI} ^/phpids(.*) RewriteRule ^(.+)$ - [F]
Configuration
The basic configuration is extremely simple. By default it comes with several examples. I recommend that you take the time to look at the original Config.ini and browse through the included documentation. It will work "out of the box" with very few edits to the Config.ini. My Config.ini looks like:
[General] filter_type = xml use_base_path = false filter_path = default_filter.xml tmp_path = tmp scan_keys = false HTML_Purifier_Path = IDS/vendors/htmlpurifier/HTMLPurifier.auto.php HTML_Purifier_Cache = IDS/vendors/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer html[] = __wysiwyg json[] = __jsondata exceptions[] = __utmz exceptions[] = __utmc min_php_version = 5.1.2 [Logging] path = tmp/phpids_log.txt recipients[] = me@domain.com subject = "PHPIDS detected an intrusion attempt!" header = "From: <PHPIDS> noreply@domain.com" envelope = "" safemode = true allowed_rate = 15 [Caching] caching = file expiration_time = 600 path = tmp/default_filter.cache
Now, we need to write a simple php script to enable PHPIDS. I used one of the included examples with minor modifications
ids.php
<?php // set the include path properly for PHPIDS set_include_path( get_include_path() . PATH_SEPARATOR . 'phpids/lib/' ); if (!session_id()) { session_start(); } require_once 'IDS/Init.php'; try { $request = array( 'REQUEST' => $_REQUEST, 'GET' => $_GET, 'POST' => $_POST, 'COOKIE' => $_COOKIE ); $init = IDS_Init::init(dirname(__FILE__) . '/phpids/lib/IDS/Config/Config.ini'); $init->config['General']['base_path'] = dirname(__FILE__) . '/phpids/lib/IDS/'; $init->config['General']['use_base_path'] = true; $init->config['Caching']['caching'] = 'file'; $ids = new IDS_Monitor($request, $init); $result = $ids->run(); if (!$result->isEmpty()) { require_once 'IDS/Log/File.php'; require_once 'IDS/Log/Email.php'; require_once 'IDS/Log/Composite.php'; $compositeLog = new IDS_Log_Composite(); $compositeLog->addLogger(IDS_Log_Email::getInstance($init),IDS_Log_File::getInstance($init)); $compositeLog->execute($result); } } catch (Exception $e) { //this shouldn't happen and if it does you don't want the notification public. } ?>
Now we will use PHP's auto_prepend_file to prepend our ids.php script from above to all other php scripts. You can do this by adding the following to your php.ini
auto_prepend_file /full/path/to/ids.php
Or with a .htaccess we can do something like:
php_value auto_prepend_file /full/path/to/ids.php
Add Comment