Subscribe to PHP Freaks RSS

Protecting php applications with PHPIDS

Print
by Thomas Johnson on Dec 20, 2008 7:33:12 PM - 61,550 views

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

Comments

rtadams89 Jan 6, 2009 12:48:55 AM

How about a little more on how it works, recommended settings, examples...

Thomas Johnson Jan 6, 2009 10:27:31 AM

I think you may have missed this part "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.".

I didn't write this tutorial to be the definitive guide for PHPIDS. The intention of this tutorial was to demonstrate a basic configuration/setup and to give the guys on the PHPIDS team some recognition for their great work. If you want a more detailed explanation I suggest that you look through their documentation - http://php-ids.org/docs.

kprichard Nov 17, 2010 10:01:36 PM

I tend to agree with rtadams89... the docs provided with PHPIDS are pretty thin soup. An article about PHPIDS could expand upon, and fill the huge gaps in, PHPIDS's minimalist documentation.

Basically, the examples provided with PHPIDS aren't much use for learning the package because they don't explain anything about how the configs are used in PHPIDS. I think we're pretty much required to read through of the source code to understand which config options are useful, and how to make them work.

And, sadly, the website's links from the word 'Documentation' point to the generated docs (from phpDocumentor), which don't offer much info about configuring it, because there's very little phpdoc-formatted knowledge in the source.

Here's an example of a better-documented config option, "safemode":

- The default config file, IDS/Config/Config.ini.php, says "note that enabling safemode you can prevent spam attempts, see documentation"
- The generated documentation, in the copy I have, doesn't mention "safemode" at all
- Instead, grepping the source, we find IDS/Log/Email.php has a couple notes about "safemode" -

"safemode...is a spam protection based on the alert frequency"

and

"If safemode is enabled, this property [$allowed_rate] defines how often reports will be sent out. Default value is 15, which means that a mail will be sent on condition that the last email has not been sent earlier than 15 seconds ago."

That you could receive up to 5,760 emails per day from your IDS would be a pretty useful piece of info, right? But that's not mentioned anywhere in the generated docs, or in this article. :)

James somewhere Feb 5, 2012 5:07:04 AM

Thank you Thomas for your works here in bringing the PHPIDS into the view of people who would not otherwise be able to see that it does exist.
As a newbie i do not see how i could change the modules in Apache on a hosted server. I would assume any leach on the host, asking for access to the mods would be questioned.
I looked into many different types of word configurations in g search queries in: host web configure Apache Modules - and that in its self - for some one on a host plan - i would needs days if not weeks researching just to find the correct information to do something that takes 5 basic minutes.
Thanks for bringing the PHPIDS to light.

Add Comment

Login or register to post a comment.