Alex Rivera | Logout

How do I sanitize a user submitted url?

Asked 2012-08-02T15:34:32.713
14

I want to store users' personal urls as plain text, encoded by htmlspecialchars().

Then I would retrieve this data and generate and display a link, as follows:

echo '<a href="'.$retrieved_string.'" target="_blank">';

And yet, even with encoded special chars and quotes, the href may not be safe, due to the potentially inserted javascript, example of a bad link:

javascript:alert(document.cookie);

So what I'm thinking is to strip up for a potential 'javascript' tag (before I do the special chars encode of course), as follows:

preg_replace('/^javascript:?/', '', $submitted_and_trimmed_input);

So let us sum it up altogether:

$input=htmlspecialchars(preg_replace('/^javascript:?/', '', trim($_POST['link'])),11,'UTF-8',true);
mysql_query("update users set link='".mysql_real_escape_string($input)."'");

//And retrieving:

$query=mysql_query("select link from users");
$a=mysql_fetch_assoc($query);
echo '<a href="'.$a['link'].'" target="_blank">';

Now the question is, would it be enough to an url link safe, or is there any other potential surprises I should be alert against?

EDIT:

I've read a bit about filter_var() and it seems to utterly fail in many ways. It doesn't validate international domains with unicode chars, then again the following string successfully passes the test:

http://example.com/"><script>alert(document.cookie)</script>
  • I mean common... that's just rediculous, there must be a better way
Edit
Report

1 Answer

-1

This is how I'm gonna do it. It looks to me the best way is to prepend it with http:

$link=preg_replace('/^(http(s)?)?:?\/*/u','http$2://',trim($_POST['website']));

So even if a script gets there I couldn't care less. Then actually convert chars:

$link= htmlspecialchars($link, 11,'UTF-8',true);

That's it. No beating around the bush, and should be utf-8 compat also.

answered 2012-08-02T18:54:48.933

Your Answer