views:

180

answers:

3

The URL would be

  1. Saved to a MySQL database
  2. Used to display a picture on the user's profile

would strip_tags() and mysql_real_escape_string() be enough?

+1  A: 

It's probably safer and better to call htmlentities() on the string instead of counting on strip_tags().

strip_tags() won't remove html special chars like '"&

e.g., if your code is:

<img src="<?= strip_tags($myVar) ?>">

and

$myVar = '">something goes here<';

then you end up with:

<img src="">something goes here<">

Which is pretty obviously the root of an XSS hole; an actual exploit is left as an exercise for the reader.

Frank Farmer
A: 

I initially upvoted Frank's answer, but thought of a problem: htmlentities() will break legal urls like this:

http://www.mywebsite.com/profile?id=jojo&amp;w=60&amp;h=60

Perhaps stripping angle brackets + mysql_real_escape would be sufficient?

justkevin
An image URL shouldn't have ampersands or such in it though?
aslum
Why not? A script is a perfectly valid source of images.
Mike Daniels
Frank Farmer
Frank Farmer
+4  A: 

"Enough sanitization" thoroughly depends on what environment you're talking about. Sanitization for MySQL should be considered entirely separate from sanitization for web output, and you should handle them separately to avoid a lot of hassle.

Sanitizing for MySQL

  • mysql_real_escape_string() will sanitize a piece of data and make it safe to put inside an SQL query.
  • Any other type of malicious data, such as HTML tags inside the string, should be absolutely ignored. Trying to manipulate it here will lead you to headaches as you try to "un-manipulate" it later after getting it out of the database. Bad "web data" cannot harm your database.

Sanitizing for output

  • htmlspecialchars($val) at output time will prevent any malicious tags from being rendered, because < and > characters are converted into their entity representations and not rendered as tag delimiters.
  • Use the ENT_QUOTES modifier if you are outputting something that is inside an HTML element's quoted attribute, such as <input name="email" value="<?php echo htmlspecialchars($email,ENT_QUOTES); ?>" />

That should be all you need, unless you have special requirements. strip_tags() shouldn't really be used for sanitization, as it can be fooled with badly formed HTML. Sanitization is a worthy goal, and if you can keep your contexts separate, you'll run into fewer problems with data manipulation between them.

zombat
+1 for only sanitizing when it's needed. Of course, sanitizing for SQL is *evil*, just use parametrized queries...
sleske
@sleske - yes, that's the prevailing wisdom these days. Sanitizing for SQL isn't evil though. Many systems will be using older database versions or drivers, and might not have access to MySQLi. The only reason sanitizing gets a bad rep is because people *forget to do it*. Prepared queries just abstract away the manual sanitization (among other advantages).
zombat
What do you mean "Parametrized Queries"?
aslum
Paramaterized queries are something offered by the PDO (http://php.net/PDO) and MySQLi (http://php.net/mysqli) driver packages for PHP. Essentially you create a query with placeholders for the data, and pass the data in separately to the query functions, where they undergo proper conversion and sanitization. If you're interested, read up on those two modules in the PHP manual and google around for examples. They are worth checking out and using.
zombat