Tutorials

Protecting php applications with PHPIDS

Views: 41272
Rating: 4/5
Votes: 3

Introduction

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/ [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