read

Here's phpids, an Intrusion Detection System for PHP.

According to the site, it aims to counter XSS, SQL Injection, header injection, directory traversal, RFE/LFI, DoS and LDAP attacks, and unknown attack patterns,  through it's Centrifuge component.

Installation is simple. Just download it, copy the lib directory to a directory in your project structure, or add it to your include_path.

I actually chose a mix of both ways, so it's automatically included when I distribute my applications.

Here's how to use it:


ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.PRIVATE_ROOT.DIRECTORY_SEPARATOR.'phpids'.DIRECTORY_SEPARATOR.'lib');

Here we're just modifying the include path in order to add phpids.
PRIVATE_ROOT is a constant that I've defined in my app, which defines the root of the application. This is not accessible from the web server (following the recommendation of the Dispatch method, from the PHP Security Consortium. However, this is a particular case, in most situations, I'd recommend using a framework that already takes a similar pattern into account, like CakePHP).
phpids is where I've copied this IDS. The downloaded package has a similar root directory name, like phpids-x.y.n, depending on the version number.


require_once 'IDS/Init.php';

Require the Init.php file

Then, whenever you need to access the request variables (in my case, this was just in one point in my application so I just had to modify one function), add something like this:


$request = array(
'REQUEST' => $_REQUEST,
'GET' => $_GET,
'POST' => $_POST,
'COOKIE' => $_COOKIE
);
$init = IDS_Init::init(PRIVATE_ROOT. DIRECTORY_SEPARATOR .'phpids'.DIRECTORY_SEPARATOR.'lib/IDS/Config/Config.ini');

$ids = new IDS_Monitor($request, $init);
$result = $ids->run();

if (!$result->isEmpty()) {
trigger_error($result);
}

If the $result object is not empty, the IDS detected an attack attempt and therefore you should stop processing the request.

And now the fun part.

In order to test this, I set up a very simple, very insecure test page.
Here's the php code:

error_reporting(E_ALL);
ini_set('include_path',ini_get('include_path').':'.'../src/phpids/lib');
require 'IDS/Init.php';
function checkIds()
{
   $request = array(
     'REQUEST' => $_REQUEST,
     'GET' => $_GET,
     'POST' => $_POST,
     'COOKIE' => $_COOKIE
);

$init = IDS_Init::init('/home/fipar/workspace/at-intranet/src/phpids/lib/IDS/Config/Config.ini');
$ids = new IDS_Monitor($request,$init);
$result = $ids->run();
if (!$result->isEmpty()) {
     trigger_error($result);
}
}

if (isset($_REQUEST['sql'])) {
     checkIds();
     $sql = $_REQUEST['sql'];
     print 'Form says '.$sql.'
';
}

The html page has just an input type text with the name 'sql', and a submit button.

I tried the following inputs:

  • Hello, which goes by ok
  • ' and 1, which generates errors for the REQUEST and POST variables, stating

    Detects classic SQL injection probings 1/2 | Tags: sqli, id, lfi | ID: 42

  • <a href="http://www.google.com">www.google.com</a>, which generates errors for the REQUEST and POST variables, stating
    • finds html breaking injections including whitespace attacks | Tags: xss, csrf | ID: 1
    • Detects JavaScript object properties and methods | Tags: xss, csrf, id, rfe | ID: 17
    • Detects basic SQL authentication bypass attempts 2/3 | Tags: sqli, id, lfi | ID: 45
Blog Logo

Fernando Ipar


Published

Image

Fernando Ipar

"Tell my wife I love her very much, she knows"

Back to Overview