I recently found a huge security problem with my PM system that allows users to send a message as much as they want with a
for loop in the address bar. Someone put this into the address bar:
And the message was sent 1000 times to me and my inbox was full of the same message and my database was so full that phpMyAdmin was being very laggy.
My question is, how can I prevent this? This is a major issue.
Also, the form is submitted with AJAX.
I use PHP, so how can I prevent this? Like how could I make it to where a message can only be sent every 5 minutes or so and if they submit more than one within 5 minutes it will display an error (or not show any user feedback at all and just stop it from being submitted)?
There is one obvious way to fix it and the problem lies not on the client side – it lies on the server side.
Your server script should not allow sending messages too often – eg. often than, say, once each 10 minutes. To do it you can use session mechanism on the server side and save the information when the user sent the email. If user has not sent an email, you should also save that information in session – to distinguish people with session enabled from people with session disabled (and you should block the latter from sending emails at all).
The way session should be implemented (the specific code) depends on the language you use for server side scripting (PHP, Python, JSP etc.).
If someone has the knowledge to do this to you, you likely cannot do anything on the client side so the only option I’d say is that you log or keep a count etc of the number of requests (perhaps to a particular resource) and deny the request (or send a “busy” http code etc) for the particular user.
I think the simplest way would be to count requests from a specific IP address (this obviously has drawbacks such as multiple users behind a proxy or NAT etc).
The actual solution will depend on your server side language and web server but you could perhaps frame up a rule and see how it works. Something like 5 requests per minute (or whatever is appropriate for your usage) per IP address.
As others have said, you have to implement protection on the server. No amount of client-side coding will provide protection.
The common way of protecting a server against this type of abuse is called
rate limiting. You decide how often you want a given client to be able to submit a message and you code the server to ignore any messages that fall outside that limit.
For example, you could decide that you will allow no more than one message a minute and no more than two messages every 10 minutes and no more than four messages an hour. You pick whatever you think seems reasonable and you code to that algorithm.
In your server, you’d have to be able to identify which user the message was coming from (most likely via an authentication cookie) and in your database, you’d have to be able to find out when the last message was sent by that user. You may even be able to cache that information in RAM in your server (depending upon how your server works) to avoid a database lookup on every request since you only have to keep recent info and you only need to performance optimize on the repeat offenders (the ones that are trying to abuse your server and thus just recently sent a request).
I agree with what everyone is posting about rate-limiting.
However, this can be very complicated to implement on the server side. Especially when you start scaling out. And, honestly, if 1000 messages hurt you that bad – my suggestion may apply to you even more so.
Instead of implementing this yourself, you may want to look into a third party service to do it for you, such as this super cool web services proxy Apigee
One of their features is, specifically, API rate throttling. (see link)