Software, your way.
burger menu icon
WillMaster

WillMaster > LibrarySecurity and Blocking

FREE! Coding tips, tricks, and treasures.

Possibilities weekly ezine

Get the weekly email website developers read:

 

Your email address

name@example.com
YES! Send Possibilities every week!

Form Probe Blocker

Most of our forms send an email as they are used. When a bot probes a form for vulnerabilities, we can get hundreds or even thousands of emails sent to us.

Yesterday, another probing session was launched on willmaster.com.

The bot was thorough. It probed every which way for server software, XSS, and MySQL vulnerabilities.

Here is a partial list of why the probes:

  1. Server software vulnerabilities can include full view of server passwords and/or other ways to gain root or domain access to the server.

  2. XSS (cross-site scripting) vulnerabilities may be used to inject the cracker's JavaScript into your web pages.

  3. MySQL vulnerabilities can give crackers access to login passwords and other confidential data that may be stored in the databases and, if they don't find what they want — or just to be mean — dump all data in your databases. (Database Back Up and Restore can be used to back up and, if needed, restore databases.)

This bot sent all of its probes individually through every form field, submitted both GET and POST, of virtually every form we have on the server — except for the spam-free forms, which it couldn't find and couldn't probe even it if found them.

This probing session spawned over 40,000 emails in about 7 hours — way over 40,000. (Yes, they did it overnight while we were sleeping.)

I'm not worried about our software; it is up-to-date with best-practice security. But dealing with those emails was annoying.

So I made a form probe blocker.

If your forms send you emails or, especially, if you are uncertain about all of your form software being secure, then seriously consider implementing this probe blocker.

How the Form Probe Blocker Works

The blocker exists on your server separate from your forms and form software. Your form software pulls in the blocker functionality with one line of PHP code.

The blocker looks for certain strings of characters that are commonly used for probing. It inspects all POST and GET field names and values.

If a probing string is recognized, the server's .htaccess file is updated to deny their IP address.

Just like that, the probing is blocked.

If they change IP addresses, the very next time they do a probe with a recognized string, that IP address is also blocked.

They can't stay ahead of the game.

Caveat: There is a remote possibility that someone will inadvertently lock themselves out. As an example, a section of a much-used string for probing is "/../../". If someone inputs "What does /../../ do?" into a protected form, they will get locked out when the form is submitted.

Consider whether or not inadvertent lock-out is acceptable for your forms.

A bright note: The above can not happen with forms from Spam-free Form — there is no danger of you not getting site owner email or anybody getting locked out of your site in that way.

Form Probe Blocker Features

The blocker checks every form field name and value, methods GET and POST, for strings of characters that indicate a probe is happening. The strings of characters are in a plain text file that you can updated as needed.

Probes can consist of a hundred or more strings of data. Most of those are variations of each other trying to find the combination that exposes a vulnerability.

It is enough for the Form Code Blocker to look for snippets of strings used in those probes — snippets that are highly unlikely to be typed during normal form use. As an example, the string "/../../" can be used in dozens of different form probes.

The bot must use all the variations to try to get through. Form Code Blocker only needs to detect one snippet and you've caught the culprit.

When there's a match, the IP address is blocked by appending data to the server's .htaccess file. The data is a comment line with time and date stamps and a line denying that IP address access to the server. It looks something like this (assuming IP address 127.0.0.1):

# 1734849534 - Sun, 22 Dec 2024 06:38:54 +0000
Deny from 127.0.0.1

Optionally, the Form Probe Blocker can send you an email when an IP address is blocked. The email would contain the IP address and all the form fields that were in the probe submission. You would get one email for each IP address that is denied via your .htaccess file.

When the blocking software is installed on your server, every PHP form handler you want to hook up to it gets one line of code (assuming blocker software location /ipBlock/FormProbeBlocker.php):

include($_SERVER['DOCUMENT_ROOT']."/ipBlock/FormProbeBlocker.php");

With that line of code, the form handling software now has the probe blocker functionality.

Because the probing bot may be launched from various IP addresses, you may end up with dozens of blocked addresses. Each block is dated so you can remove the old blocks if the .htaccess file becomes larger than you are comfortable with. Or a cron-launched script can remove the ones older than a certain age.

The Form Probe Blocker Source Code

Install and test the source code for the Form Probe Blocker before hooking it up to live form software.

There are two parts, the PHP software and the plain text file with probe strings to test.

Both the Form Probe Blocker PHP software and the text file with probe strings need to be in the same subdirectory.

Here is the PHP software source code. Save it as FormProbeBlocker.php or other *.php file name you prefer. Customizing notes follow.

<?php
/*
Form Probe Blocker - .htaccess Update
Version 1.0
May 27, 2019
Will Bontrager Software LLC
*/

/* Customizing section */
$EmailAddress = "name@example.com";
date_default_timezone_set("UTC");
$ProbeTestStringsFileName = "ProbeTestStrings.php";
$htaccessFileLocation = "/.htaccess";
/* End of customizing section */

$Location = preg_replace('!/[^/]+$!','',__FILE__);
$LocationOfTestStringFile = "$Location/$ProbeTestStringsFileName";
$ProbeTestStrings = array();
$lines = file($LocationOfTestStringFile);
$count = count($lines);
for( $i=1; $i<$count; $i++ )
{
    $line = trim($lines[$i]);
    if( substr($line,0,1) == '#' ) { continue; }
    if( ! preg_match('/\S/',$line) ) { continue; }
    $ProbeTestStrings[] = $line;
}
$Blockit = false;
CheckArrayAgainstStrings($_GET);
if( ! $Blockit ) { CheckArrayAgainstStrings($_POST); }
if( $Blockit )
{
    $Content = date('r')."\nIP: {$_SERVER['REMOTE_ADDR']}\nSelf: {$_SERVER['PHP_SELF']}\n\$_GET ".print_r($_GET,true)."\$_POST ".print_r($_POST,true);
    if(strpos($EmailAddress,'@')) { mail($EmailAddress,"IP blocked: {$_SERVER['REMOTE_ADDR']}",$Content,"From: $EmailAddress"); }
    file_put_contents("{$_SERVER["DOCUMENT_ROOT"]}$htaccessFileLocation","\n# ".time().' - '.date('r')."\nDeny from {$_SERVER['REMOTE_ADDR']}\n",FILE_APPEND);
    exit;
}

function CheckArrayAgainstStrings($arr)
{
    global $Blockit;
    foreach( $arr as $k => $v )
    {
        $Blockit = CheckLItemAgainstStrings($v); if( $Blockit ) { break; }
        $Blockit = CheckLItemAgainstStrings($k); if( $Blockit ) { break; }
        $Blockit = CheckLItemAgainstStrings(rawurldecode($v)); if( $Blockit ) { break; }
        $Blockit = CheckLItemAgainstStrings(rawurldecode($k)); if( $Blockit ) { break; }
        $Blockit = CheckLItemAgainstStrings(html_entity_decode($v)); if( $Blockit ) { break; }
        $Blockit = CheckLItemAgainstStrings(html_entity_decode($k)); if( $Blockit ) { break; }
    }
}

function CheckLItemAgainstStrings($s)
{
    global $ProbeTestStrings;
    $blockMatch = false;
    foreach( $ProbeTestStrings as $string )
    {
        if( preg_match('/'.preg_quote($string,'/').'/',$s) )
        {
            $blockMatch = $s;
            break;
        }
    }
    return $blockMatch;
}
?>

Customizing notes:

There are four values that may be customized in the customization section. Only the first is required.

  1. $EmailAddress = "name@example.com";

    This is the required customization: Replace name@example.com with either (a) the email address where the software shall send a notice whenever it denies an IP address or (b) nothing (the current email address removed).

    If the value contains an email address, the notice email is sent. If the value is blank, no notice email is sent.

  2. date_default_timezone_set("UTC");

    When the .htaccess file is appended with a denial for a specific IP address, a comment line immediately above the denial line contains the date and time of occurrence. The function parameter UTC specifies that the date and time are of the UTC timezone (same time as GMT).

    The UTC time zone designation may be changed. You may change UTC to your own timezone. Timezone designations can be found at the Timezone Designations for PHP Software page.

  3. $ProbeTestStringsFileName = "ProbeTestStrings.php";

    (The source code for the plain text file with probe strings for Form Probe Blocker to test follows these customizing notes.) If the probe test strings file is saved with a file name other than ProbeTestStrings.php, then ProbeTestStrings.php needs to be changed to the new file name.

  4. $htaccessFileLocation = "/.htaccess";

    The above /.htaccess specifies that the .htaccess file in the document root directory is the one to update when an IP address needs to be denied. If you wish a different .htaccess file to be updated, change /.htaccess to the new location.

That's all for the customization section of the FormProbeBlocker.php script.

Here is the plain text file with probe strings for Form Probe Blocker to test. Save it as ProbeTestStrings.php or other *.php file name you prefer. Customizing notes follow.

<?php exit; ?>
# Lines beginning with "#" are ignored.
# The first line of this file prevents the  
#   rest of this file from being viewed with  
#   a browser or bot.

# Blank lines are OK in this file.

# Probe strings follow. If any of these 
#   match what was input into your form,  
#   or their hex version, it is virtually  
#   certain your software is being probed.

\.\.\
/././
/.\\./
/../../
-1 OR 
-1" OR 
-1' OR 
etc/passwd
win.ini
boot.ini
Li4vLi4vLi4v
waitfor delay '
waitfor delay "
<script alert(
WEB-INF/web.xml
WEB-INF\web.xml
select pg_sleep(
(select convert(int,
if(now()=sysdate(),sleep(
(select(0)from(select(sleep(

Customizing notes:

There is unlikely to be a need to customize this file right away. It can be used as is. In the future, you may determine that certain strings need to be added, removed, or deleted.

The <?php exit; ?> must remain as the first line of the file. It's purpose is to block the file content from browsers and bots. The Form Code Blocker FormProbeBlocker.php software jumps over the first line when it reads the file.

The content colored blue are fragments of strings that are likely to be used when a bot probes form software. These may be added to, removed, and modified if you ever need to do so.

Installing and Testing (Carefully)

After customizations are done and both the Form Probe Blocker software file and the plain text file with probe strings have been uploaded to the same directory, it is time to carefully test the system.

Two things need to be done before testing:

  1. Download a copy of the .htaccess file on your server as a backup. Keep the file where it won't be overwritten if you download .htaccess again.

    The reason for making a backup .htaccess file is in case something goes awry or for another reason the file has to be restored.

  2. Keep a copy of the Tor browser handy. You test with Tor because it uses an IP address different than yours.

    The entire reason for using Tor during installation and testing is for the different IP address. If you test with your own IP address, you will block yourself from your own domain web pages. (You could, of course, restore the .htaccess file from your backup to let yourself back in.)

    If you do not have Tor on your hard drive, it can be downloaded from the Tor Project.

Install and Test — Step One:

When the above two "before testing" items are complete, use Tor to load the URL of your FormProbeBlocker.php script. If there are any error messages, they need to be attended to before continuing.

Now, it is time to test the IP address blocking.

Install and Test — Step Two:

You are using Tor, right? If not, use Tor.

In the Tor browser's address bar, where the URL of your FormProbeBlocker.php script is at, append ?test=/../../ to the URL. Tap the enter key.

That should block the IP address Tor is using. Test by using Tor to load any page on your website.

(Get IP Address and User-Agent String can be used to obtain the IP address Tor is using — and the user-agent string it presents.)

If you still can load a page on your website with Tor, check these two things:

  • The .htaccess file might not have been updated. Check to see if the .htaccess has a line beginning with Deny from and ending with an IP address appended to the bottom.

    If not, the .htaccess file needs to be made writable. Giving the file 777 permissions should do the trick. Try that and then do the entire Step Two again.

  • Tor intermittently changes the IP address it uses. If the .htaccess was updated as it should have been, then Tor may have changed its IP address between the block setting action and the page load test. Do this entire Step Two again to verify.

If Tor is successfully forbidden from loading a web page on your domain, then the Form Probe Blocking software is working.

If you can't get to that point, there is something awry with the installation and it may need to be redone from scratch.

Install and Test — Step Three:

Now that the form probe blocking system is working, it is time to hook up a form to the system. And then test it.

If you're doing this immediately, the Tor IP address may still be blocked. It can be unblocked by restoring the backup .htaccess file or by removing the Deny from … line that was added to the .htaccess file. Tor needs access in order to test your form after you've hooked it up.

Your form submits to somewhere. That somewhere is the form processing software. The form processing software might be the same page where the form is at or it might be a different URL.

To work with Form Probe Blocker, the form processing software needs to be a PHP web page or script. In the form processing software, find a place where <?php starts a line. Leave a space or linefeed after <?php and insert this (with one customization, see note following):

include($_SERVER['DOCUMENT_ROOT']."[LOCATION]");

Replace [LOCATION] with the server location of your FormProbeBlocker.php script. The server location is the URL of the script minus the leading http:// (or https://) protocol and domain name. As an example, URL https://example.com/ipBlock/FormProbeBlocker.php would be /ipBlock/FormProbeBlocker.php for the server location.

The form is now hooked up. Test it with Tor.

With Tor, submit the form normally to verify it works as it should.

Next, in one of the form fields, type /../../ and submit the form. When you do that, IP address Tor is using at that moment should get blocked. Test it by trying to load any web page at your website.

With the Tor IP address blocked, test the form with your regular browser with normal use to verify it still works as it should.

When that first form works as expected — the form can be used normally but it will block the IP address when a designated probe string is used — then it is good to go.

Do this Step Three for each of your other forms that you want to hook up to the Form Probe Blocker.

Occasional Cleanup

If your forms experience a lot of probe tests by various bots, the .htaccess file may become thousands of lines long. This is unlikely, but it's possible.

To clean that up a bit, download the .htaccess file, remove the oldest Deny from … lines (the date immediately above the Deny from … line indicates when the line was added), then upload the modified .htaccess file.

The lines may be removed after several weeks anyway should you prefer to do so. If the same IP address tries another probe, it will get blocked again.

Oh, and if you ever lock yourself out, remove the Deny from … line with your IP address so you can get back in. (The Deny from … lines block only HTTP and HTTPS access. You can still access your server with FTP.)

Why Probing?

Form probing occurs for various reasons, from a friendly test to see how the form works to testing for vulnerabilities with malicious intent.

The form probe blocker is versatile. It comes pre-loaded with common probe test strings. You can update the probe test strings as you deem necessary.

When a test string is found in any of the form fields, method GET or POST, the bot's IP address is immediately blocked.

The blocking is done with the server's Deny from … file. The file may be edited to unblock specific IP addresses.

With Form Probe Blocker installed and hooked up to your forms, you have quite a bit of protection from malicious form probes.

(This article first appeared with an issue of the Possibilities newsletter.)

Will Bontrager

Was this article helpful to you?
(anonymous form)

Support This Website

Some of our support is from people like you who see the value of all that's offered for FREE at this website.

"Yes, let me contribute."

Amount (USD):

Tap to Choose
Contribution
Method

All information in WillMaster Library articles is presented AS-IS.

We only suggest and recommend what we believe is of value. As remuneration for the time and research involved to provide quality links, we generally use affiliate links when we can. Whenever we link to something not our own, you should assume they are affiliate links or that we benefit in some way.

How Can We Help You? balloons
How Can We Help You?
bullet Custom Programming
bullet Ready-Made Software
bullet Technical Support
bullet Possibilities Newsletter
bullet Website "How-To" Info
bullet Useful Information List

© 1998-2001 William and Mari Bontrager
© 2001-2011 Bontrager Connection, LLC
© 2011-2024 Will Bontrager Software LLC