NAME
HTTP::ProxyTest - Reject an HTTP request if passed via an open proxy
SYNOPSIS
use HTTP::ProxyTest;
proxytest(
-nmap => '/usr/local/bin/nmap',
-whitelist => '/usr/local/etc/ProxyTest_whitelist',
-log => '/var/log/open_proxy.log',
);
DESCRIPTION
Robots that send comment spam are often hidden behind anonymous open proxy servers. You can use HTTP::ProxyTest
to look for open proxies on-the-fly and prevent such spam robots from submitting their crap. The module is particularly useful if you don't want to bother your web site visitors with CAPTCHAs etc.
HTTP::ProxyTest
tests certain ports of REMOTE_ADDR
that are often used for anonymous open proxies, and denies access if an open proxy is found, i.e. it responds with status "403 Forbidden" and exits. The module was designed to make use of the Nmap security scanner (http://nmap.org/) in order to speed up things and/or increase the number of ports to be considered for testing. Consequently, if Nmap is currently not available to you, you are advised to download and install that program.
The strong point of HTTP::ProxyTest
, compared to other similar CPAN modules (see "SEE ALSO"), is its speed. Since Nmap limits the number of ports to test, HTTP::ProxyTest
can do on-the-fly testing fast enough to cover quite a few proxy port candidates, without causing any significant response delay. The same seems not to be true for other modules.
Arguments
Below are the arguments that can be passed the proxytest() function, which by the way is the only function of HTTP::ProxyTest
that you are supposed to call from outside the module. proxytest() takes hash style key=>value arguments (see "SYNOPSIS"). All the arguments are optional.
- -nmap
-
Path to the nmap executable; no value by default.
If -nmap is set,
HTTP::ProxyTest
will test those -primary ports that Nmap reports to be either open or filtered, while it will only test those -secondary ports that Nmap reports to be open.If -nmap is not set,
HTTP::ProxyTest
will test all the -primary ports and skip the -secondary ports. - -primary
-
Reference to an array of ports where the risk of carrying an open proxy is not insignificant. Default value:
[ 80, 3128, 8080 ]
- -secondary
-
Reference to an array of ports which are less likely, compared to the -primary ports, to carry an open proxy. Default value:
[ 808, 6588, 8000, 8088 ]
- -test_url
-
Web address used for proxy testing; defaults to
'http://example.net'
. If you pass the -test_url argument to change this value, you'd better choose a URL to a tiny page on a reliable server which includes the status line200 OK
in the responses. - -content_substr
-
A string that shall be included in the content string of the response; defaults to
'/rfc2606'
. To prevent false positives,HTTP::ProxyTest
will not report that a host carries an open proxy, unless it has confirmed an occurrence of -content_substr in the response content string.Obviously, if you set -test_url, you will most likely need to set -content_substr as well.
- -timeout
-
When doing proxy testing,
HTTP::ProxyTest
expects to establish a server connection within -timeout seconds after a request, or else the request is aborted. Defaults to 4. - -whitelist
-
Path to a DBM database with IP addresses of hosts that passed the proxy tests during the last week; no value by default. If you set -whitelist,
HTTP::ProxyTest
will maintain the database and skip testing for hosts in the 'whitelist'. - -log
-
Path to a text file where information about requests from hosts with open proxies is logged; no value by default.
- -log_maxbytes
-
Maximum size in bytes of the -log file; defaults to
1_000_000
. If -log is set, and when the max size is touched,HTTP::ProxyTest
halves the file size by removing the oldest entries.
EXAMPLES
Perl web apps
After having adapted the "SYNOPSIS" code, you can simply insert it e.g. before any form generating or form data processing code portion of a Perl program. To shorten the code to be inserted in various programs, you can place a wrapper in one of the @INC
directories.
# proxytest.pl
use HTTP::ProxyTest;
proxytest(
-nmap => '/usr/local/bin/nmap',
-whitelist => '/usr/local/etc/ProxyTest_whitelist',
-log => '/var/log/open_proxy.log',
);
1;
Now you can invoke HTTP::ProxyTest
by just saying:
require 'proxytest.pl';
PHP web apps
This example of how to invoke HTTP::ProxyTest
from PHP begins with this script, located in one of the PHP include_path
directories:
<?php
// proxytest.php
function proxytest() {
$args = implode(' ', array(
getenv('REMOTE_ADDR'),
getenv('HTTP_HOST'),
getenv('REQUEST_URI'),
));
exec('/path/to/proxytest.pl ' . $args, $error);
if ( count($error) ) {
header('HTTP/1.0 403 Forbidden');
echo ( implode( "\n", array_slice($error, 3) ) );
exit;
}
}
proxytest();
?>
Then we add some code to the wrapper and make it an executable Perl script.
#!/usr/bin/perl
# proxytest.pl
use HTTP::ProxyTest;
if ( $ENV{_} and $ENV{_} eq '/path/to/proxytest.php' ) {
@ENV{ qw/REMOTE_ADDR HTTP_HOST REQUEST_URI/ } = @ARGV;
}
proxytest(
-nmap => '/usr/local/bin/nmap',
-whitelist => '/usr/local/etc/ProxyTest_whitelist',
-log => '/var/log/open_proxy.log',
);
1;
Finally the single line call from a PHP program:
include 'proxytest.php';
DEPENDENCIES
This module is dependent on the libwww-perl set of modules.
Also, even if it's possible to use HTTP::ProxyTest
without access to the Nmap security scanner, we'd better consider Nmap to be a 'soft dependency', a.k.a. strong recommendation.
CAVEAT
In case of HTTP::ProxyTest
being invoked via a server wide wrapper, and the web server may be run as more than one user (e.g. because of Apache suEXEC), you should pay attention to the permissions of the DBM and log files. You may want to make sure that those files are 'world writable'.
AUTHOR, COPYRIGHT AND LICENSE
Copyright (c) 2010 Gunnar Hjalmarsson
http://www.gunnar.cc/cgi-bin/contact.pl
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.