2

On my server I have magic_quotes turned off. When a user save content as article in my DB from a form, I use

$text = mysql_real_escape_string($_POST['text']); to prevent SQL Injecion.

This is my input <img src="image.png"></img> and this is what it is saved in the DB <img src="image.png"></img>

When I echo htmlentities($row['text']); i get <img src="image.png"></img> printed on screen, on view source I get &lt;img src=&quot;image.png&quot;&gt;&lt;/img&gt;.

My questions are

  1. Isn't supposed to be saved in DB like <img src=\"image.png\"></img> to prevent SQL Injections ?
  2. Is htmlentities is a good candidate to prevent XSS attacks?
  3. Should I turn on magic_quotes?
EnexoOnoma
  • 8,454
  • 18
  • 94
  • 179
  • `strip_tags` is fine, except that you can still get into trouble with it. E.g.: ``. For this reason, I'd suggest using Markdown or some Wiki-style language. – Chris Laplante Aug 25 '11 at 19:50

4 Answers4

2

Isn't supposed to be saved in DB like <img src=\"image.png\"></img> to prevent SQL Injections ?

No, SQL injections are widely misunderstood, mainly because they actually have nothing to do with SQL as they are just string manipulation. You don't need to alter the data you insert into the database, you only have to alter the string you send to the database server as query (unless you do the wise choice and use prepared statements instead of escaping the query string). The data, once stored, should be in its original state.

Is htmlentities is a good candidate to prevent XSS attacks?

Yes but htmlentities() is good for sending data as output to the browser, not for storing it into the database (as the data from the DB might be used for something other than a web page).

Should I turn on magic_quotes?

No, you should use prepared statements.

Matteo Riva
  • 24,728
  • 12
  • 72
  • 104
  • Thank you for your answer. My application is really basic and simple, so I choosed to avoid prepared statements for the moment. I agree that PDO, prepare staments are a must to use. My question is why does the image did not showed up but I got `` on screen ? – EnexoOnoma Aug 25 '11 at 20:37
  • Well it depends. If you're happy with `mysql_real_escape_string` that's fine. In your specific case I don't see the need to save the whole image tag in the db, when you can just save the image path and write the tag in the output. If however you still want to do that, you must not use `htmlentities()` when printing it if you want it to be parsed as an HTML tag. `htmlentities()` or (better) `htmlspecialchars()` is used when you **don't** want some text to be parsed as HTML tag(s). – Matteo Riva Aug 25 '11 at 20:39
  • Ok, `` was just an example. Let's say `text` because users will be able to post content with HTML. I read that `htmlspecialchars()` are not secure enough. Is that right ? – EnexoOnoma Aug 25 '11 at 20:44
  • Regarding web page security, `htmlentities()` and `htmlspecialchars()` are identical, the former just transforms more characters, but the basic ones are converted by both. If you need to deal with user data such as comments, I would suggest using `strip_tags()` instead, so you can choose which tags you want to allow and which ones you want to exclude, so that your output won't be littered with unparsed tags. – Matteo Riva Aug 25 '11 at 20:49
0

Use mysql_real_escape_string and turn the quotes back to normal:

$text = str_replace('\"', '"', $row['text']); // Alternative one
$text = preg_replace("/X/", '"', $row['text']); // Alternative two. X needs to be \\", \\\" or \\\\", perhaps \\\\\"

Answers to updated questions:

Correct saving of data goes like this:

input -> php - > mysql_real_escape_string -> db -> php -> htmlspecialchars -> browser

Melissa
  • 1
  • 1
0
  1. It seems that your magic quotes is enabled. Check it.
  2. There are a lot of articles about this but for quick starting don't allow to use javascript and external images.
Andrej
  • 7,474
  • 1
  • 19
  • 21
0

Getting escaped data out of the database suggests it's been double-escaped - does your PHP have magic_quotes_gpc turned on? If you want to sanitize HTML and allow only certain constructs you specify through, then I suggest using HTMLPurifier which'll get as strict or lax as you want.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • Hello can you please check my updated answer ? I just turned magic_quotes off. – EnexoOnoma Aug 25 '11 at 20:11
  • Escaping should only last through one layer of transmission. If you do escaping once for PHP->database, the escapes are removed and the data is stored in the database WITHOUT the escapes. The fact that you still had escapes for the data coming OUT of the database mean you were effective escaping twice (though PHP was just using addslashes, which is NOT secure). htmlentities will completely destroy the html by turning itinto the equivalent of plain text. if you want to allow actual html, you'll have to use Purifier to filter/sanitize it for you. – Marc B Aug 25 '11 at 20:14