I've made a voting on comments like the one this website has(something similar), and I'm slightly concerned about possible http request misuse. You'll know what I mean after I show you the questionable code:
$.ajax({
type: 'POST',
url: 'http://localhost/comments/vote_down/' + post_id
});
Now its still on localhost but it will get to the web eventually. What if someone just makes some kind of script which will run n times
this url http://localhost/comments/vote_down/post_id
.
Not even user authentication is very helpful, you just tweak your malicious script to authenticate and you can do it again. How can I make this request more secure, what can I do? thank you
EDIT
I see some answers , not the ones I've been looking for so far.
Maybe I'm expecting too much, is there a way I can directly refuse this request to anyone but someone redirected from localhost(or website.com), after x attempts to do so .
Maybe some kind of header authentication? I'm not very into that that is the main reason why I ask.
EDIT
Also what I've discovered accidentaly about a minute or so ago, I was browsing trough few similar questions and my firebug was on, I added one question to favorites .. saw console post response 200 OK
then I tried it for like 10 times just to see when will I be rejected to do the same again.. eventually I got bored .. so if StackOverflow didn't solve that .. what am I trying to do :=)
At the bare minimum, you can make sure that every user can only vote once.
Additional options:
In response to your edit:
If you are talking about checking for a valid referring page, you are out of luck. That is incredibly easily spoofed. You can implement a token check where you generate a hash that is valid for X seconds and deny all requests with an invalid or expired hash. This will not prevent people from voting multiple times though.
In response to your second edit:
A status code of 200 only means that the http request was successful, what the application logic decided to do with the request is a completely different issue. You can deny the vote and return a 200, just as you can return a 403 (which would probably be more appropriate in this case though).
You are going to have to do more than store the vote tally for a post id. You are going to have to store a record for each individual vote cast.
Once your database schema is set up for that, you can start to associate additional information with each vote - an IP address, user id, etc.
Most places only allow authenticated users to vote, and only allow a user to vote once for any given post id. Stackoverflow goes beyond that and allows users to undo their votes and recast them.
If requiring a user to be authenticated before they can vote is not acceptable, then you can go by IP address and then throttle the number of votes to be able to be cast from that IP at some interval. For instance, once a vote is cast from XXX.XXX.XXX.XXX, it cannot vote again for another 15 minutes. This will not break the Internet for people behind a proxy, but will reduce the amount of gaming that can be done.
You could go even further and try to detect someone gaming the system and then blacklist them for some amount of time.
You must authenticate via a token.
Potentially, I could just print a <img src="http://localhost/comments/vote_down/1">
and start casting votes from users who are accessing my site.
What you must do is a server-side validation, let's say you will validating against a MD5 hash ( md5(1)
= c4ca4238a0b923820dcc509a6f75849b
)
http://localhost/comments/vote_down/1?hash=c4ca4238a0b923820dcc509a6f75849b
Now on your server you must hash the post_id and check if the hash params matches, if it does, then allow to vote.
But then I could still just keep spamming votes from users without knowing via <img src="http://localhost/comments/vote_down/1?hash=c4ca4238a0b923820dcc509a6f75849b">
What you'll have to do is hashing both the post_id and user_id (from session), that way one hash from one user won't be the same to another.
User: 1
Post_id: 1
md5(11) = 6512bd43d9caa6e02c990b0a82652dca
User: 2
Post_id: 1
md5(12) = c20ad4d76fe97759aa27a0c99bff6710
Obviously, you should salt the hash function, but even with out it, your app will be pretty secure that way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With