awohld has asked for the wisdom of the Perl Monks concerning the following question:

I have a guy submitting thousands of bogus posts to my website's payment form. I'm starting a database to log his IP address and attempt times so if I notice any IP posting more than several times per hour that it will lock this guy out of the form.

What is the best way to track a person's IP address with Perl?
Is $ENV{'REMOTE_ADDR'} spoofable?
Are environment variables good enough or is there anything else?

Thanks

Replies are listed 'Best First'.
Re: Unique User Logging and Lock Out
by cfreak (Chaplain) on Nov 17, 2004 at 22:53 UTC

    It is spoofable but not as easily as HTTP_REFERER. Not saying not to check it but use it along with other methods of verification

    There are several things you can do to help yourself besides just $ENV variables.

    First of all if you can I'd block the offending IP at the firewall. If you don't have access to the firewall but you're using Linux and have some kind of admin privilege you can add the IP to the /etc/hosts.deny file. Or use iptables.

    If your form is generated then use a signature to sign the page and then submit it along with your form. Make a random MD5 and store that somewhere with the IP address. Then when the form is submitted use the signature to retrieve the IP used to load the page and compare the two. Denying if there is no signature or the signature isn't stored, or the IPs don't match. Make sure to delete the stored stuff after the comparison (wheither it passed or failed) you might want to store a timestamp as well and expire the signatures.

    At the very least this approach will slow an attack down because it will force an attacker to get the correct signature for every submit to your form. You can still lock the IP if it connects too much as well, forcing any attacker to keep changing or spoofing new ones, hopefully giving up.

    Having good input checking will also help. Deny if the same information has already been submitted. And make sure the information you accept is carefully looked over. Only allow generally accepted formats for names, address, phone-numbers, etc. And make sure your numerical fields only contain numbers. You don't have to lock out people who make mistakes but you keep the information from reaching your database or payment processor. Plus you force the person to get a new signature. Transparent if they are using your app, but more difficult for automated tools.

    HTH

Re: Unique User Logging and Lock Out
by ikegami (Patriarch) on Nov 18, 2004 at 00:22 UTC

    $ENV{'REMOTE_ADDR'} is the address of the remote end of the connection on which the HTTP request was received. In other words, it's the address from which the request came, and it's the address to which the answer will be returned. Assuming you trust your web server, the address can only be spoofed if the user can guess the sequence number the web server used to start the conversation (since it's TCP, and not UDP). That's not easy (which doesn't meant it's not possible), and I've never heard of it being done outside of academics. I read a good article discussing how vulnerable TCP sequence numbers are, but I can't find it.

    It doesn't mean it's his IP address, however. He could be using another machine as a proxy or tunnel, or he could be controlling a web client on a remote machine.

Re: Unique User Logging and Lock Out
by Anonymous Monk on Nov 18, 2004 at 04:53 UTC
    HTTP headers, such as REMOTE_ADDR, could as ikegami pointed out, could easily refer to an in-between proxy server and not the user.

    A malicious user could pull off some list of public anonymous proxies and script requests through each of them at random intervals, which makes it very hard to filter out bad requests.

    You could implement a CAPTCHA (Completely Automated Public Turing Test to Tell Computers and Humans Apart), in order to stop automated requests. There are several implementations out there, for example GD::SecurityImage.

    As a sidenote, most non-anomyous proxies set the HTTP_X_FORWARDED_FOR header which usually is the users IP, however if proxies several proxies were chained together, it would be a commadelimited list of the proxies IPs. HTTP_VIA and HTTP_CLIENT_IP are other ones I remember from the top of my head. These variables enable you to identify proxies and distinguish users behind it.

Re: Unique User Logging and Lock Out
by Miguel (Friar) on Nov 17, 2004 at 22:21 UTC
    I'd use $ENV{'HTTP_REFERER'} too. This way you can check if the request came from an allowed source (your server and your previous page) or not. It's not 100% trustable... but it's one more barrier.

    Something like this:

    my $allow; $ENV{'HTTP_REFERER'} eq "MY_SERVER_MY_PAGE" ? $allow = 1 : $allow = 0;

    To add some more difficulty to the proccess of injecting trash into your forms you could use session-variables and/or cookies.

    the problem with blocking IPs is you never know who's behind the computer. Could be a legitimate person, trying to buy something, or could be a smart guy trying to ruin your business.

Re: Unique User Logging and Lock Out
by Anonymous Monk on Nov 17, 2004 at 21:06 UTC

    $ENV{REMOVE_ADDR} should come from the web server, so I don't think that's spoofable, but....

    Is he coming from the same IP all the time? Is he coming from the same IP range? If so, find out who owns the address and contact the ISP, or the ISP's ISP.

      This guy is from Bulgaria, I emailed his ISP but I'm not sure if they can read my email/English. He's coming from the same IP address. I can block out his entire range but I suspect he may just come from another route.
Re: Unique User Logging and Lock Out
by ww (Archbishop) on Nov 17, 2004 at 21:49 UTC
    To paraphrase another cliche -- Everything's spoofable except me and thee
    ... and I'm not so sure about thee.

    Nonetheless seems like a reasonable plan, coupled with advise below.

Re: Unique User Logging and Lock Out
by Vennis (Pilgrim) on Nov 18, 2004 at 11:07 UTC
    If banning his IP address or range doens't work (like he finds another way to post) then you might not really lock him out, but redirect these 'suspicious' orders to a seperate 'box' that you can check on later.

    More like a spam-filter.

    This will make him think his posts worked (Fool the fool) while your real orders will be seperated from the trash.

    Q: Why did the Perlmonk cross the road?
    A: He wanted to escape the match.

Re: Unique User Logging and Lock Out
by mkirank (Chaplain) on Nov 19, 2004 at 13:40 UTC
    If your server has mod_perl , then you can look at Apache::SpeedLimit