4

I have developed a bulletin board from scratch using CodeIgniter, PHP, and PDO for MySQL. Now I'm currently cleaning it up and testing for defects / security flaws. I came across a minor defect that I cannot think of a solid solution for. Users can flood my database with random comments that are not even associated with any forum posts. To better describe this issue let me briefly explain my system.

When you sign in to view a post, the post object along with any related comments via post_id are pulled from the database. You can choose to read the post and leave your own comment. The comment form towards the bottom has a hidden field called pid which stores the id of the current post we are viewing so I can keep the state when you click the submit button. However there is a downfall to this. The hidden field can be modified to whatever integer value before being submitted as you could probably guess.

The URL scheme looks something like when you're viewing a post;

http://www.domain.com/forum/post/22

And after pressing submit, you will be redirected to a URL that looks like;

http://www.domain.com/forum/create_comment

... where the comment information will be inserted into the database along with associated user id and post id.

I tried testing against a referer URL but the case is similar. I've came up with several solutions but I don't know if any of them are idea? Enforcing JavaScript, storing the pid into a session, and/or obsucating the information hidden in the field.

Codist
  • 1,198
  • 2
  • 11
  • 28
  • If you have a FK constraint on the post_id on your comments table mysql won't let you insert a row with a post_id that doesn't exist. – VBCPP Mar 26 '14 at 19:52
  • @VBCPP That won't cover things like guessing the ID of a post that's in a private forum you can't access, though. – ceejayoz Mar 26 '14 at 19:54
  • @ceejayoz Exactly! That would only stop the comment from sitting there in the database until the post with that id is eventually created. – Codist Mar 26 '14 at 19:55
  • @ceejayoz correct, but that concern wasn't mentioned in the question. I would handle permissions issues before the insert. If the pid is 23 & user has permission to post on 23, I would let them, regardless of whether or not they changed it – VBCPP Mar 26 '14 at 20:01
  • @VBCPP I've got a permission system setup so if users try to post on a private post it won't let them unless they are a mod, admin, or invited to leave a comment. That is not an issue because it won't let them post to a private post ids but the thing is, they can still randomly insert comments to posts that exist from different posts. A good idea though! I could intertwine this with ceejayoz answer. – Codist Mar 26 '14 at 20:05
  • @W3Geek I guess I'm not seeing the issue. If they have permission to post on post 23, why does it matter if they changed the id on page 22 into a 23? Anyway feel free to ignore, gl&hf – VBCPP Mar 26 '14 at 20:11
  • @VBCPP The issue is minor like mention before, really it's more than a nuisance than anything. I just don't want users editing primary key information on it and leaving trails of spam behind if that makes any sense. – Codist Mar 26 '14 at 21:56

1 Answers1

5

You can't enforce JavaScript, storing the pid in a session is going to drive anyone with multiple tabs nuts, and obfuscation never works well.

One potential solution is using a salted hash to verify the data. For example:

<input type="hidden" name="pid" value="<?= $pid ?>" />
<input type="hidden" name="pid_hash" value="<?= sha1('this is my salt' . $pid) ?>" />

On submission, you'd reject anything where the hash doesn't fit the pid value. As the salt is never exposed to the user's browser, they should have a difficult time faking it for a non-existent pid.

ceejayoz
  • 176,543
  • 40
  • 303
  • 368
  • Thats an situation I thought about but wasn't sure about the tabs. By enforcing JavaScript I meant stopping the forum from loading if noscript is used. Your tip is really helpful! Are there anymore solutions revolving backend? For some reason I cannot wrap my head around any. – Codist Mar 26 '14 at 19:54
  • @W3Geek Never, ever rely on JavaScript to protect you. A determined user can get around any client-side protection you attempt, as they have full access to and control of the scripts being executed. – ceejayoz Mar 26 '14 at 19:55
  • @ceejayoz In which they always will. I didn't want to do this at all. It might slow down some users but it isn't full on protection. That's why I wanted to rely on the backend. *Edit* Just seen the end of your post. – Codist Mar 26 '14 at 19:58
  • Also giving the fields random names would probably help and offsetting them somewhere else in the HTML might throw them off from editing the values. – Codist Mar 26 '14 at 20:00