Take the 2-minute tour ×

I want to allow users of my site to post urls. These urls would then be rendered on the site in the href attributes of a tags. Basically, user A posts a url, my site displays it on the page as an tag, then user B clicks it to see pictures of kittens.

I want to prevent javascript execution and xss attacks, and ensure there are no malformed urls in the output I generate.

Example: User A posts a malformed url, supposedly to pictures of kittens. My site tries to generate an tag from user A's data, then user B clicks the resulting link. User A has actually posted a malformed url which adds a javascript "onclick" event in the to send the victim's cookies to another site.

So I want to only allow correctly formed urls, and block out anything other than http/https protocols. Since I'm not allowing anything here which doesn't look like a url, and the user is not providing me html, it should be pretty simple to check by parsing and reforming the url.

My thinking is that parse_url should fail with an error on malformed urls, or it replaces illegal characters with '_'. I can check the separated parts of the url for allowed protocols as well. Then by constructing a url using http_build_url, I take the parts separated by parse_url and put them back together into a url which is known to be correctly formed. So by breaking them down this way first, I can give the user an error message when it fails instead of putting a sanitized broken url in my page.

The question is, will this prevent xss attacks from doing evil if a user clicks the link? Does the parsed and rebuilt url need further escaping? Is there a better way to do this? Shouldn't this be a solved problem by now with functions in the standard php libraries?

I really don't want to write a parser myself and I'm not going to even consider regular expressions.


share|improve this question
add comment

3 Answers

up vote 0 down vote accepted

What you need to do is just escape content properly when building your html. this means that when a value has a " in it, you build your html with &quot;

Protecting against XSS isn't primarily about validating URL's it's about proper escaping. (although you probably want to be sure that it's a http: or https: link)

For a more detailed list of what to escape when building html strings (ie: the href attribute) see HTML, URL and Javascript Escaping

share|improve this answer
add comment

No, parse_url is not meant to be a URL validator.

You can use filter_var for this:

filter_var($someURL, FILTER_VALIDATE_URL);
share|improve this answer
add comment

Depending on a few other things, you might just validate the URL by checking if it points to any content. Here is an example:

figure 1


// URL to test
// $url = "";

$content = file_get_contents($url);


echo "Success:<br /><iframe src=\"$url\" style=\"height:400px; width:400px; margin:0px auto;\"></iframe>";


echo "Failed: Nothing exists at this url.";



Curl is another option. With cURL you can just return http headers then check the error code it returns. ie Error 404 = page not found, 200 = OK, 201 = Created, 202 = Accepted, etc etc

Good luck!

~John http://iluvjohn.com/

share|improve this answer
Implementing this on a production website where you most likely would get $url as user input would pose a serious security threat, so don't do it. –  Bjørn Børresen Mar 20 '12 at 11:34
add comment

Your Answer


