XSS: REQUEST_URI run through htmlspecialchars() - then replacing & with & - enough to prevent XSS injection?
Scenario:
I would like to replace: " ' < >
with " ' < >
but keep the "&" character.
The string I'm dealing with is a URL and I want URL parameters to be separated by &
, not &
.
Example Solution:
$url = "/some/path?a=123&b=456"; // from $_SERVER["REQUEST_URI"];
$url = htmlspecialchars($url, ENT_QUOTES, 'ISO-8859-1', true);
$url = str_replace('&','&',$url);
Question:
If I use $url
on my page (e.g. echo $url;
inside HTML or JavaScript) can this be exploited by XSS?
Similar Questions:
There are other posts on SO covering XSS &
htmlspecialchars()
but I can't find an answer around whether the "&" character (and the htmlentities it may allow) can expose you to XSS.
Is replacing : < and > wit开发者_开发知识库h < and > enough to prevent XSS injection?
is htmlspecialchars() in PHP or h() in Ruby on Rails good enough for defending all cases of XSS (Cross-site scripting) attacks?
Sijmen Ruwhof made this interesting point that I feel is relevant:
http://www.php.net/manual/en/function.htmlentities.php#99896
The 'ENT_QUOTES' option doesn't protect you against javascript evaluation in certain tag's attributes, like the 'href' attribute of the 'a' tag. When clicked on the link below, the given JavaScript will get executed:
<?php
$_GET['a'] = 'javascript:alert(document.cookie)';
$href = htmlEntities($_GET['a'], ENT_QUOTES);
print "<a href='$href'>link</a>"; # results in: <a href='javascript:alert(document.cookie)'>link</a>
?>
I once used really weird code for escaping urls, but I bet this can be done better, furthermore this does not cover the html specialchars yet, it was just used for saving urls to the database.
function escapeUrl(&$url){
$matches = parse_url($url);
if(!isset($matches["host"])){
Utils_Logging_Logger::getLogger()->log(
"Unknown host for URL: \"$url\".",
Utils_Logging_Logger::TYPE_ERROR
);
$matches["host"] = "";
}
if(!isset($matches["scheme"])){
Utils_Logging_Logger::getLogger()->log(
"Sheme (like http://) for URL: \"$url\" was not set.",
Utils_Logging_Logger::TYPE_LOG);
$url = "http://";
}else{$url = $matches["scheme"]."://";}
$url.=$matches["host"];
if(isset($matches["path"])){
$path = rawurldecode($matches["path"]);
$url.=$path;
}
if(isset($matches["query"])){
$query = rawurldecode($matches["query"]);
$url.="?".$query;
}
return $url;
}
精彩评论