Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make my code more secure

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 :=)

like image 953
Gandalf StormCrow Avatar asked Jan 27 '10 23:01

Gandalf StormCrow


3 Answers

At the bare minimum, you can make sure that every user can only vote once.

  • If user is not logged in, don't alow voting.
  • If user is logged in, restrict voting to one vote per comment (whether they can change the vote from up to down or not is up to you)
  • If you want to let unregistered users vote, lock them out with cookies and ip address and useragent checking. (Far from bulletproof, but will keep some troublemakers at bay)

Additional options:

  • Implement a captcha

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).

like image 74
code_burgar Avatar answered Nov 10 '22 23:11

code_burgar


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.

like image 41
Bryan Batchelder Avatar answered Nov 11 '22 00:11

Bryan Batchelder


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.

like image 30
metrobalderas Avatar answered Nov 10 '22 23:11

metrobalderas