BBQ: Protect Against Malicious URL Requests

[ BBQ: Block Bad Queries ] Block Bad Queries (BBQ) is a simple script that protects your website against malicious URL requests. BBQ checks all incoming traffic and quietly blocks bad requests containing nasty stuff like eval(, base64_, and excessively long request-strings. This is a simple yet solid solution that works great for sites where .htaccess is not available. The BBQ script is available as a plugin for WordPress or standalone script for any PHP-powered website.

Installation

WP Plugin: Upload the /block-bad-queries/ directory and activate the plugin via the WP Admin. Then sit back and enjoy the automatic, behind-the-scenes protection and a more secure website. Download BBQ WP Plugin.

PHP script: The plugin and script contain identical code. To implement BBQ on a non-WP site, include the script at the beginning of each web page and you should be good to go. Download BBQ PHP script.

Verify that it’s working

Once BBQ is installed, you can verify that it’s working by requesting the following URLs from your site (example.com):

  • http://example.com/proc/self/environ
  • http://example.com/path/?q=%2e%2e
  • http://example.com/path/base64_

These are just examples of the type of garbage that’s blocked by BBQ. If your server returns a 403 “Forbidden” response for these examples, BBQ is doing its thang. More tests are possible using the patterns contained in the BBQ firewall (see source code).

How it works

This is basically an adaptation of my G-series blacklists ported to PHP. It works by defining a set of regular expressions that match and block malicious URL requests. BBQ scans three parts of each request:

  • The Request URI
  • The Query String
  • The User Agent

Checking these variables against a strategically crafted set of known attack patterns is an effective way to protect against malicious attacks.

More information

Check the following articles for more information on the underlying functionality:

Plus many more articles on this and related topics in the security and .htaccess archives.

Download BBQ plugin for WordPress

Download the new and improved BBQ from the WP Plugin Directory:

WP Plugin: Block Bad Queries (BBQ)

BBQ standalone PHP script

To use BBQ on non-WP sites, include the following code for each page request:

<?php
/*
Plugin Name: Block Bad Queries (BBQ)
Plugin URI: http://perishablepress.com/block-bad-queries/
Description: Automatically protects WordPress against malicious URL requests.
Author: Jeff Starr
Author URI: http://monzilla.biz/
Version: (standalone)
License: GPL v2
Usage: No configuration necessary. Upload, activate and done. BBQ blocks bad queries automically to protect your site against malicious URL requests.
Tags: security, protect, firewall, php, eval, malicious, url, request, blacklist
*/

$request_uri = $_SERVER['REQUEST_URI'];
$query_string = $_SERVER['QUERY_STRING'];
$user_agent = $_SERVER['HTTP_USER_AGENT'];

// request uri
if (	//strlen($request_uri) > 255 || 
	stripos($request_uri, 'eval(') || 
	stripos($request_uri, 'CONCAT') || 
	stripos($request_uri, 'UNION+SELECT') || 
	stripos($request_uri, '(null)') || 
	stripos($request_uri, 'base64_') || 
	stripos($request_uri, '/localhost') || 
	stripos($request_uri, '/pingserver') || 
	stripos($request_uri, '/config.') || 
	stripos($request_uri, '/wwwroot') || 
	stripos($request_uri, '/makefile') || 
	stripos($request_uri, 'crossdomain.') || 
	stripos($request_uri, 'proc/self/environ') || 
	stripos($request_uri, 'etc/passwd') || 
	stripos($request_uri, '/https/') || 
	stripos($request_uri, '/http/') || 
	stripos($request_uri, '/ftp/') || 
	stripos($request_uri, '/cgi/') || 
	stripos($request_uri, '.cgi') || 
	stripos($request_uri, '.exe') || 
	stripos($request_uri, '.sql') || 
	stripos($request_uri, '.ini') || 
	stripos($request_uri, '.dll') || 
	stripos($request_uri, '.asp') || 
	stripos($request_uri, '.jsp') || 
	stripos($request_uri, '/.bash') || 
	stripos($request_uri, '/.git') || 
	stripos($request_uri, '/.svn') || 
	stripos($request_uri, '/.tar') || 
	stripos($request_uri, ' ') || 
	stripos($request_uri, '<') || 
	stripos($request_uri, '>') || 
	stripos($request_uri, '/=') || 
	stripos($request_uri, '...') || 
	stripos($request_uri, '+++') || 
	stripos($request_uri, '://') || 
	stripos($request_uri, '/&&') || 
	// query strings
	stripos($query_string, '?') || 
	stripos($query_string, ':') || 
	stripos($query_string, '[') || 
	stripos($query_string, ']') || 
	stripos($query_string, '../') || 
	stripos($query_string, '127.0.0.1') || 
	stripos($query_string, 'loopback') || 
	stripos($query_string, '%0A') || 
	stripos($query_string, '%0D') || 
	stripos($query_string, '%22') || 
	stripos($query_string, '%27') || 
	stripos($query_string, '%3C') || 
	stripos($query_string, '%3E') || 
	stripos($query_string, '%00') || 
	stripos($query_string, '%2e%2e') || 
	stripos($query_string, 'union') || 
	stripos($query_string, 'input_file') || 
	stripos($query_string, 'execute') || 
	stripos($query_string, 'mosconfig') || 
	stripos($query_string, 'environ') || 
	//stripos($query_string, 'scanner') || 
	stripos($query_string, 'path=.') || 
	stripos($query_string, 'mod=.') || 
	// user agents
	stripos($user_agent, 'binlar') || 
	stripos($user_agent, 'casper') || 
	stripos($user_agent, 'cmswor') || 
	stripos($user_agent, 'diavol') || 
	stripos($user_agent, 'dotbot') || 
	stripos($user_agent, 'finder') || 
	stripos($user_agent, 'flicky') || 
	stripos($user_agent, 'jakarta') || 
	stripos($user_agent, 'libwww') || 
	stripos($user_agent, 'nutch') || 
	stripos($user_agent, 'planet') || 
	stripos($user_agent, 'purebot') || 
	stripos($user_agent, 'pycurl') || 
	stripos($user_agent, 'skygrid') || 
	stripos($user_agent, 'sucker') || 
	stripos($user_agent, 'turnit') || 
	stripos($user_agent, 'vikspi') || 
	stripos($user_agent, 'zmeu')
) {
	@header('HTTP/1.1 403 Forbidden');
	@header('Status: 403 Forbidden');
	@header('Connection: Close');
	@exit;
} ?>

Note that this script is somewhat different than the current version of the WP plugin. Newer versions of the plugin are optimized to work better with WordPress, but this version of BBQ continues to protect non-WP sites in general.

Support

Questions and comments about BBQ welcome in the comments, or contact me directly.