I want to block the same repeating requests to my website. For example, someone hits "Refresh" button 3 times, so I want the same requests following from that user to be auto blocked.

I know I can do that with PHP or whatever server-side programming language is used, but is there any "portable" solution independent of the website, like Apache2 config or iptables rule?

Are there any other methods of such basic protection?

  • Typical work for the bofh! – pkhamre Aug 16 '12 at 8:29

I'm pretty sure that if you could even manage to make this work in iptables it would be a very bad idea. iptables understands layers 3 and 4 of the OSI model; HTTP requests are in layer 7.

Since HTTP is a stateless protocol and you are trying to give a different response based on the current state, you will need some method of keeping track of state. The normal way of doing this is with cookies although this is not the only way to keep track of state. mod_rewrite has the ability to set and read cookies and match them with regular expressions so we'll try that first.

You can use these rules to cause any page request that's too soon after another to be blocked:

RewriteRule (\.html|\.php)$ - [CO=recent:true:example.com:1:/]

RewriteCond %{HTTP_COOKIE} recent=true
RewriteRule (\.html|\.php)$ - [F]

The first rule causes a cookie to be set for every .html or .php page with an expiry time of one minute. The next pair or rules causes any request for a .php or .html page with that cookie (i.e. within one minute) to be rejected. After a minute the cookie should expire and no longer be sent.

There are drawbacks here: It doesn't restrict itself to the same URL, so every page request has to be a minute after the previous one and the expiry time is in minutes, so one minute is the shortest possible time. You are limited to 403 responses which aren't necessarily very friendly or informative. That's about the best I can manage with Apache. nginx has a more programming-like configuration language which may allow you to do the URI comparison needed to only block page refreshes and not other requests.

Using PHP (or whatever) to put the current URL and timestamp in the session (or storing the IP address and source port in a database along with the current URL and timestamp. You would do this if your clients don't support cookies.) would allow you to do the comparison. If the current URL and the one in the session are the same, and the timestamp is within some threshold of the current time, you could send them a different response. With PHP (as opposed to Apache) you could send a 503 response (which makes more sense) with some appropriate text to explain why they are getting that response instead of the page they expected.

The best option in my mind is Javascript and/or key binding. Bind the keys that do a refresh (Cmd + R on a Mac, Ctrl + R, F5 everywhere) so you can intercept them and use Javascript to suggest that the user waits a bit longer before hitting refresh. This option has the best user experience and has the lowest impact on your server.

  • Thank you for the Cookie and JS suggestions! But they're not that reliable since, for example, bots are likely to have them disabled. So I guess the DB or even log file tracking would be my only 99% reliable option. And then JS may be used to improve user experience. – aexl Aug 19 '12 at 8:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.