Bonfocchi
Bonfocchi

Reputation: 523

How do I protect against HTML injection in a URL form field with PHP?

For example if I am colecting a [URL value] in a form, saving that [URL value] in a database, and then using it in a page like this:

<a href="[URL value]" > The Link </a>

How do I protect against this [URL value]:

http://www.somelink.com"> Evil text or can be empty </a>  ALL THE EVIL HTML I WANT  <a href="

How can I protect against this kind of HTML injection for URL form fileds without breaking the URL in case it is valid ?

Upvotes: 0

Views: 5255

Answers (5)

p0deje
p0deje

Reputation: 4053

For escaping when displaying use htmlentities($var, ENT_QUOTES) or htmlspecialchars($var, ENT_QUOTES). It's needed to escape both single and double quotes because of browser-specific XSS payloads. Check here - http://ha.ckers.org/xss2.html

Also, when validating URL javascript: URI is not the only one dangerous. Other one is data: URI.

Anyway, it's always more secure to exclude everything except whitelisted, then to include everything except black-listed.

Upvotes: 0

emurano
emurano

Reputation: 973

EDIT: Just use urlencode, do not use htmlentities as well

Whenever you put data into the key/value pairs of a URL, you should encode that data using urlencode(). This function will take care of any special characters that syntactic meaning in the way URLs are meant to be constructed. Ampersands, equal signs and question marks will be encoded for you. All the angle brackets AND new line characters in the inject HTML will be encoded too!

<?php $TheVariable = $_REQUEST['suspect_var']; // Untrusted data ?>


<a href="http://www.mysite.com/script.php?untrusted_data=<?php echo urlencode($TheVariable) ?>">The Link</a>

Upvotes: 0

Alex Jasmin
Alex Jasmin

Reputation: 39496

When receiving the URL on the form:

  • Use filter_var(url, FILTER_VALIDATE_URL) to ensure the URL is in a valid format.
  • Ensure the URL starts with http:// or https:// (or at least reject all javascript: URL as they can include malignant code)
  • Use prepared statements when inserting the URL (and other form data) in the database or properly escape that data to prevent SQL injections.


When displaying the page:

  • Use htmlspecialchars() to escape the URL (and all other text) that you insert in the HTML.

Upvotes: 6

cambraca
cambraca

Reputation: 27839

Use urlencode to encode just the " sign when printing the url, like:

echo '<a href="'.str_replace('"', urlencode('"'), $url).'">link name</a>';

Upvotes: -1

Jeremy
Jeremy

Reputation: 2669

The simplest way to do that would be to check that the input contains what looks like a syntactically valid url, with no characters such as > which are not allowed in URL's. The easiest way to do that is using the filter extension. The code to do it would be like this:

if (filter_var($url, FILTER_VALIDATE_URL)) {
    //Valid URL submitted
} else {
    //Invalid URL submitted
}

Upvotes: 1

Related Questions