1

I need to know the best method to prevent XSS issue in my website.

<form action="<?php echo htmlspecialchars($page)?>" method="post">
<input class="btn btn-default" type="submit" value="Continue">
</form>

The $page value is taken from the url :

www.xyz.com/redirect.php?page=home.php

The PHP code to get the $page value :

$page=$_GET['page'];

The link causing XSS:

www.xyz.com/redirect.php?page=javascript:alert(document.cookie)

Thanks

lost111in
  • 207
  • 1
  • 3
  • 12
  • Possible duplicate of [How to prevent XSS with HTML/PHP?](http://stackoverflow.com/questions/1996122/how-to-prevent-xss-with-html-php) – RamenChef Jul 30 '16 at 18:22
  • use `htmlentities()` instead of `htmlspecialchars()` http://php.net/manual/en/function.htmlspecialchars.php and http://php.net/manual/en/function.htmlentities.php `This function is identical to htmlspecialchars() in all ways, except with htmlentities(), all characters which have HTML character entity equivalents are translated into these entities. ` And if that doesn't work then do `str_replace('javascript:', '', $page)` on that link. – ArtisticPhoenix Jul 30 '16 at 18:25
  • That said, you should just avoid injecting the page by the url and use something like `$_SESSION` to store it, instead. – ArtisticPhoenix Jul 30 '16 at 18:31
  • 1
    @ArtisiticPhoenix using htmlentities() makes no difference, the script is still executed. Using Session just transfers the problem from one variable to other as the destination page is given by user and can have other GET variables. – lost111in Jul 30 '16 at 18:33
  • @lost111in - I realize that, that's why I said to remove the `javascript:` it's a url, not html after all. `$_SESSION` is less accessible, then `$_GET`, technically this is not XSS, because if it's supplied by the user, they can hack themselves yes, but what is the point of that. XSS is if you save something and share it with another user, such as a comment or transfer a user to another domain. I can get my cookie anytime I want, I cant get your cookie. Not with that url, unless they can supply a domain that is different then your site. Even then it is them that is supplying the url, – ArtisticPhoenix Jul 30 '16 at 18:41
  • 1
    @ArtisiticPhoenix removing javascript: seems like a hack because then I will have to replace things like Javascript: / characters encoded some other way etc. so looking for better solution. Also if alert can be executed I fear something else like making some ajax calls to their own website with cookie values may be possible and the link they can share with other users of the website to get their login details. – lost111in Jul 30 '16 at 18:47
  • So all they would get is their own cookie, which you can just get out of the browser anyway. The XSS comes if they can save data on your site with that code in it and then have it presented to another user. Typically this would involve putting it in the DB. It's not a problem. – ArtisticPhoenix Jul 30 '16 at 18:47
  • You should be filtering invalid URLs, rather than trying to encode them. See http://php.net/manual/en/function.filter-var.php – rjdown Jul 30 '16 at 18:49
  • 1
    @ArtisiticPhoenix if alert can be executed I fear something else like making some ajax calls to their own website with cookie values may be possible and the link they can share with other users of the website to get their login details. – lost111in Jul 30 '16 at 18:51
  • @lost111in - for themselves they can, yes. but how does that help them steal another users cookies. – ArtisticPhoenix Jul 30 '16 at 18:53
  • 1
    @ArtisiticPhoenix your understanding of XSS is very wrong. lost111in you are right to be fearful for exactly the reason you mentioned. It could do something as simple as dynamically add an img tag to the page, with the url containing any sensitive information from the page that they wanted. – rjdown Jul 30 '16 at 18:53
  • @rjdown - you can add an image tag with, htmlentities on there. Really? The only issue would be if they shared the url with another user and had ajax in it. They would have be able to share it separate from your site, and then the user will still have to submit the form. – ArtisticPhoenix Jul 30 '16 at 18:55
  • https://www.owasp.org/index.php/Cross-site_Scripting_(XSS), please note `, to a different end user. ` AND Type-II XSS. – ArtisticPhoenix Jul 30 '16 at 18:58
  • 1
    @ArtisiticPhoenix that is exactly the point lost111in was making. `to a different end user`! If you need more clarification, please open a question. That is what the site is for. – rjdown Jul 30 '16 at 19:01
  • 1
    anyway @lost111in I strongly recommend filtering over encoding whenever possible. Makes things a lot tighter security-wise. – rjdown Jul 30 '16 at 19:03
  • 1
    @ArtisiticPhoenix , suppose user X gives the website link to user Y , just like referral links, and the link is like : `www.example1.com/redirect.php?page=javascript:var xmlhttp = new XMLHttpRequest();xmlhttp.open("GET", "http://www.example2.com", true);xmlhttp.send(); ` now if www.abc.com has Cross-Origin Request enabled, then the session data can be passed with the call and user X can login as user X. – lost111in Jul 30 '16 at 19:03
  • @rjdown can you please give more detail, I am not sure if there is some URL filtering option to try, – lost111in Jul 30 '16 at 19:04
  • try `filter_var($url, FILTER_VALIDATE_URL)` - there are more flags if you need to tweak it e.g. `FILTER_FLAG_HOST_REQUIRED` http://php.net/manual/en/filter.filters.validate.php – rjdown Jul 30 '16 at 19:05
  • @lost111in - so we have to be able to give another user a link, have cross-origin enabled, and have https only off on the session cookies, and then they need to actually submit the form. That's a lot of supposing to do. Is it vulnerable, yea slightly. Could `str_replace('javascript:' ..` and htmlentities fix that as I said before... – ArtisticPhoenix Jul 30 '16 at 19:09
  • @rjdown thanks it seem to work, but needs the entire url like `http://www.example.com/home.php` instead of relative url.`home.php` – lost111in Jul 30 '16 at 19:15
  • Ah, can you not just whitelist the pages then? – rjdown Jul 30 '16 at 19:19
  • @rjdown I am not sure how to whitelist the page urls with GET variables like `home.php?user=abc&new=true` and `login.php?refer=123&p=30` all redirected through the same page – lost111in Jul 30 '16 at 19:25
  • You could probably just whitelist the pages themselves e.g. login.php and home.php. Leave the variable validation to the page itself. – rjdown Jul 30 '16 at 19:27
  • @rjdown I think changing the url to absolute seems like the easier and better solution rather than whitelisiting every single page. Thanks for your help. – lost111in Jul 30 '16 at 19:33

1 Answers1

0
<?php
$page= filter_input(INPUT_GET, 'page', FILTER_SANITIZE_SPECIAL_CHARS);

//or
// $page= strip_tags($_GET['page']);
?>
<form action="<?=$page?>" method="post">
<input class="btn btn-default" type="submit" value="Continue">
</form>