2

I'm making a website that allows users to store user preferences in a database, including links.

But i've realised that if a user enters javascript: // Malicious code here they can execute any javascript on the page, including the ability to get session ID's.

( The links are shown to other users, thus I want to prevent this from happening )

I've tried the following things to prevent this but they all don't work:

htmlentities()
htmlspecialchars()
strip_tags()
addslashes()

Quick example of my code:

$link  = // queried from the database.
$title = // queried from the database.

echo '<a href="'. $link .'">'. $title .'</a>';

If you know how I could fix this it would be very much appriciated.

7
  • 2
    They can't do anything they couldn't already do by opening the Javascript console. Commented Jun 29, 2014 at 23:15
  • 1
    Unless you're showing the links to different users than the ones that set them. Commented Jun 29, 2014 at 23:16
  • 1
    Just enforce that the link starts with http. Commented Jun 29, 2014 at 23:16
  • @Barmar, Users have the ability to add a link to a personal page, if any other user would visit they would run the malicious code; thus allowing for their accounts to get hacked. Commented Jun 29, 2014 at 23:16
  • Take a look at what happens if you try to put javascript:something in your website address in your StackOverflow profile. Commented Jun 29, 2014 at 23:20

3 Answers 3

3

You can test link with FILTER_VALIDATE_URL

Here is an example

if(!filter_var($url, FILTER_VALIDATE_URL))
  {
  echo "URL is not valid";
  }
else
  {
  echo "URL is valid";
  }
Sign up to request clarification or add additional context in comments.

Comments

2

You should whitelist URLs by protocol. There are too many ways to obfuscate javascript: by varying case, inserting NULs, BOMs, space characters, etc. for a simple test to reliably identify all javascript: URLs.

If you want to allow only URLs with protocol

  1. http
  2. https
  3. mailto
  4. tel

then you can test your input against a regex like

/\A(?:https?:\/\/|mailto:|tel:|[^:]*(?:\/|\z))/i

which will pass any URL that has one of the protocols above, and any relative (or protocol relative) URL that does not have a colon before the first /.

Comments

1

You'll need to test the links, probably with a regular expression, possibly '^https?://'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.