I have an input box for for INSERTing into the database. It is written in PHP PDO. Some one typed in:


and also:

' onClick='alert(1);

I'm assuming they were in two different input boxes. But somehow, the user was able to modify the a field in the database to a negative number when the only way (if doing it right which is by pressing a button) is to increment by +1 or -1. For example, user presses the "+1" button, it will +1 in the database. If they press "-1" in the database. They have a negative number of -50 or something like that. What could they have done? What is my website vulnerable of?

Here is the code:

$insertQuery = $dbh->prepare("INSERT INTO fcomments (poster, lid, post_id, comment, time_stamp) VALUES(:user_id, :lid, :post_id, :comment, :timeNow)");

It looks like all the values are binded. Not sure what could be the problem?


Are PreparedStatements sufficient?

PreparedStatements are not sufficient on their own.

You should step through your code and ask yourself what is necessary, and what is possible. Step through on both the client and the server side, and see what data gets sent, if it's possible to modify it, and what it does. See what things you can do.

I can't see the rest of your code, but at first glance this code looks like it could be vulnerable to multiple Direct Object Reference exploits. You may be inserting values into the database without checking to see if these values are valid, or that they should be changed, or that the user is even authorized to change those values.

INSERT INTO fcomments (poster, lid, post_id, comment, time_stamp) 
VALUES(user_id, lid, post_id, comment, timeNow

Just because you bind these variables doesn't mean they aren't exploitable. Let's try a test case. Let's make up some ajax test cases (I am assuming 'lid' is upvote amount): callAjaxDatabaseUpdate(post_id, lid);

Now let's call it: callAjaxDatabaseUpdate(25, 100);

You're expecting it to be exactly as they entered it, like so:

INSERT INTO fcomments (poster, 100, 25, comment, time_stamp) 
VALUES(user_id, lid, post_id, comment, timeNow

What if I change the data in transit? :(

Questions you need to ask yourself

Let's look at your bound parameters:


Should the user be able to submit the user_id? Should the lid be submitted? This all looks like stuff the user could change if you're sending it via the client.

Let's say you want to make a post, right? Let's make a post then:

postDataToForum(user_id, lid, post_id, comment);

Because you know who is logged in at the time, you can grab their user_id and use it to submit things in your sql statement, etc. No big deal, right?

Well, here's a potential problem with that: I can hit F11 and go into the developer console and change those values, or I could use a program like TamperData for FireFox to find out what is being sent, and then modify it in transit.

So you expect this:

postDataToForum(23, 100, 450, "Hi everyone");

But the intruder looks through your user list, or even uses a random number, and alters the data:

// user_id = 1 = admin.
postDataToForum(1, 100, 450, "I have altered the input. Pray I do not alter it further.");

And then it shows the admin as having posted, instead of the user. This DOR exploit could be everywhere in your web application. In the case of your upvote, the user could've entered "-1", and you didn't check for that.

| improve this answer | |
  • Wow, thanks for the info! What kind of injection/attack is that called? Can you point me into the right direction to all the types of injections/attacks that are possible and what to do about them? Thanks! – hackfree111 Jan 15 '16 at 17:24
  • Check the link I gave you in the post. Direct object reference exploit – Mark Buffalo Jan 15 '16 at 17:28
  • Visit the OWASP top ten – Mark Buffalo Jan 15 '16 at 17:33
  • Thanks again! Maybe this questions is too broad but how does Facebook do it? Does Facebook or Twitter have all of these vulnerabilities secured? – hackfree111 Jan 15 '16 at 17:37
  • They're most likely secured. However, in the past, there have been many failures. Even top banks have been vulnerable to this exploit, and others. You can Google more about it. The OWASP website offers a very good starting point. – Mark Buffalo Jan 15 '16 at 17:38

Your code handles the SQL insertion correctly. I have two guesses about the attack:

  • The attacker could have repeated the request several times, and your code doesn't check if it has already downvoted the post.
  • The attacker have sent a lot of downvote requests in a very short period of time, allowing him/her to exploit a time of check / time of use race condition.
| improve this answer | |
  • Thanks for your answer. There is only one button. It is either upvote or downvote. If you have already upvoted the post, the button will show downvote and you can only downvote and also vice versa. Do you think it is XSS injection/attack? – hackfree111 Jan 15 '16 at 16:03
  • Ok, I looked up XSS and it says this: "Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted web sites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user." Another user's data was affected by this as well. So can it be XSS injection/attack? – hackfree111 Jan 15 '16 at 16:05
  • Also if it is an XSS injection/attack, how can I prevent it? – hackfree111 Jan 15 '16 at 16:08
  • @hackfree111: this has nothing to do with XSS. What happens if the user opens two tabs with a unvoted post, and downvotes it in both tabs? Does it do -1 or -2? – Benoit Esnard Jan 15 '16 at 16:18
  • @hackfree111 And what if they just send the same HTTP request that's sent by the button by other means? Anyone can open up Firebug and examine the network traffic then reproduce it using Postman or a similar tool. – Alfred Armstrong Jan 15 '16 at 16:29

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