Jacek Kowalewski
Jacek Kowalewski

Reputation: 2851

How to block the link from malicious bot visitors?

I'm producing an event registration website. When someone click on a link:

<a href="/reserve/10" rel="nofollow">Reserve id=10 event</a>

The system is doing a "lock" on this event for ten minutes for this visitor. In that case no one else can reserve this event in next ten minutes. If the payment is done in that time, everything is OK, else the event is unlocked again. I hope the idea is clear.

PROBLEM: When bot (google bot, malicious bot, or angry customer script :P) visits this page, he see this link. Then he enters the page. Then the lock is done...

Also if someone visit recursive: /reserve/1, /reserve/2, /reserve/3, ... He can lock all the events.


I thought about creating a random md5 string for each event. In that case, every event has (next to id) unique code, for example: 1987fjskdfh938hfsdvpowefjosidjf8243

Next, I can translate libraries, to work like this:

<a href="/reserve/1987fjskdfh938hfsdvpowefjosidjf8243" rel="nofollow">
    Reserve
</a>

In that case I can prevent the "bruteforce" lock. But the link is still visible for bots.

Then I thought about entering the captcha. And that is the solution. But captchas are... not so great in case of usability and user experience.


I saw few websites with reservation engine working like this. Are they protected? Maybe there is a simple ajax / javascript solution to prevent the bots from reading this as a pure text? I thought about:

<a href="/registerthisvisitorasbot" id="reserve">Reserve</a>
<script type="text/javascript">
    $('#reserve').click(function(e) {
        e.preventDefault();
        var address = ...; 
        // something not so obvious to follow? 
        // for example: md5(ajaxget(some_php_file.php?salt=1029301))
        window.location('/reserve/' + address);
    });
</script>

But I'm not sure what shall I do there to prevent bots form calculating it. I mean stupid bots will not be able even to follow javascript or jquery stuff, but sometimes, someone wants to destroy something, and if the source is obvious, it can be broken in few lines of code. And whole database of events will be locked down with no reservation option for noone.

Upvotes: 1

Views: 807

Answers (2)

Vogel612
Vogel612

Reputation: 5647

IP-Specific maximum simultaneous reservations

Summary: Depend on the fact that many simple bots operate from one host. Limit the number of simultaneous reservations for a host.

Basic scetch:

  • Store the requesting IP alongside the reservation
  • On reservation request count the IP's which have a non-completed reservation.

    SELECT Count(ip) FROM reservations WHERE ip=:request_ip AND status=open;
    
  • If the number is above a certain threshold, block the reservation.

(this is mostly an expansion of point 4 given in avetist's excellent answer)

Upvotes: 1

avetisk
avetisk

Reputation: 12319

CRFS + AJAX POST + EVENT TOKEN generated on each load.

Summary: don't rely on GET requests especially through a elements.

And better if you add some event block rate limits (by IP for instance).

EDIT: (this is a basic sketch)

  1. replace all the href="..." with data-reservation-id=ID
  2. delegate click on the parent element for a[data-reservation-id]
  3. in the callback, simply make a POST ajax call to the API
  4. in the API's endpoint check rate limits using IP for instance
  5. if OK, block the event and return OK, if not return error.

Upvotes: 3

Related Questions