0

My site has a form with a comment field. If someone enters, for example:

"What" is 'up'?> 

into the comment field, it gets inserted into mysql using PDO prepared statement and subsequently appears in the database exactly like this:

\"what\" is \'up\'?>

Then when I pull that data back out of the database, I use:

$comment=htmlspecialchars($row['comment']);

But when I output it to the page using "echo $comment", it gets outputted to the page as:

\"what\" is \'up\'?>

Shouldn't htmlspecialchars remove those slashes?

FWIW, before converting to PDO, I used to use mysqli_real_escape_string() before inserting and then htmlspecialchars() before displaying.

Insert code:

$comment=$_POST['comment'];

$stmt = $pdo->prepare("INSERT into details (firstname, lastname, comment) values (:firstname, :lastname, :comment)");

$stmt->execute([':firstname' => $firstname, ':lastname' => $lastname, ':comment' => $comment]);
user3304303
  • 1,027
  • 12
  • 31
  • 2
    Do you have magic quotes on? (you shouldn't). Please add the code where you're storing the comment to the db, just to make sure it isn't escaped (mangled) in any way – JimL Aug 03 '17 at 15:36
  • 1
    Are you using prepared statements? You don't need to clean strings on input **at all** if you are. – GrumpyCrouton Aug 03 '17 at 15:36
  • 1
    I believe `htmlspecialchars()` should [only be used when you are outputting](https://stackoverflow.com/a/4882317/1022914). – Mikey Aug 03 '17 at 15:39
  • 1
    For input, all you need is prepared statements with placeholders in the query. For output, you can use `htmlspecialchars()` to prevent invalid HTML and possibly Js. That function is intended for output **only**. – Qirel Aug 03 '17 at 15:39
  • 2
    "Shouldn't htmlspecialchars remove those slashes?" — No, they shouldn't be in there in the first place. – Quentin Aug 03 '17 at 15:41
  • @JimL, magic quotes are disabled. – user3304303 Aug 03 '17 at 15:48
  • 1
    By any chance did you use `mysqli_real_escape_string()` and then insert the values using a mysqli prepared statement? I believe that would have double escaped the values so you'd end up with extra slashes. (Normally the slashes _should not show up_ in the database.) – Don't Panic Aug 03 '17 at 15:52
  • @Don't Panic, that's exactly what it was, thank you! So sorry to everyone who chimed in that I didn't notice that (it was oddly much higher up on the page, so I didn't see it, but I should have checked more thoroughly) – user3304303 Aug 03 '17 at 15:59

1 Answers1

0

Your database should contain proper data:

"what" is 'up'?>

If it contains trash like:

\"what\" is \'up\'?>

Then many things will break, like full-text search, sorting, basically anything that manipulate text. You can't even use LENGTH() or SUBSTRING()! So this must be fixed ASAP.

Something's wrong in the part of the code which inserts/updates values.

  • magic_quotes could be activated (an excellent way to corrupt data)
  • stray addslashes() in your code
  • double-escaping with mysql_real_escape_string() or similar
  • escaping + prepared stmt

Good hunting. This is annoying to fix.

Also, while you're at it, check your encoding. Who knows, when someone enters "é" maybe "é" gets inserted! (This also breaks SQL UPPER(), LOWER(), SQL sorting, LIKE searches, basically nothing works).

My address contains both a ' and a é. Sometimes when I receive online orders... Yes, I received envelopes with \\' and "é" actually printed on them. This is how you know the webshop uses php!

Now, once your database contains proper data, nothing stops your users from entering this in their forum posts:

<script type="text/javascript"> StealAllYourCookies(); </script>

So this is why you use htmlspecialchars() when outputting stuff into your html.

bobflux
  • 11,123
  • 3
  • 27
  • 27