XSS: REQUEST_URI проходит через htmlspecialchars (), а затем заменяет & на & - достаточно, чтобы предотвратить внедрение XSS? - PullRequest
1 голос
/ 17 марта 2011

Сценарий:

Я хотел бы заменить: " ' < > на &quot; &#039; &lt; &gt; , но оставить символ "&" .

Строка, с которой я имею дело, является URL, и я хочу, чтобы параметры URL были разделены &, а не &amp;.

Пример решения:

$url = "/some/path?a=123&b=456"; // from $_SERVER["REQUEST_URI"]; 
$url = htmlspecialchars($url, ENT_QUOTES, 'ISO-8859-1', true); 
$url = str_replace('&amp;','&',$url);

Вопрос:

Если я использую $url на своей странице (например, echo $url; внутри HTML или JavaScript), может ли это быть использовано XSS?

Похожие вопросы:

На ТАКом покрытии есть другие посты XSS & htmlspecialchars() но я не могу найти ответ вокруг ли "&" характер (и htmlentities это может разрешить) может подвергнуть вас XSS.

Ответы [ 2 ]

1 голос
/ 17 марта 2011

Sijmen Ruwhof сделал этот интересный момент, который я считаю уместным:

http://www.php.net/manual/en/function.htmlentities.php#99896

Опция 'ENT_QUOTES' не защищает вас отоценка javascript в атрибутах некоторых тегов, таких как атрибут 'href' тега 'a'.При нажатии на ссылку ниже, данный JavaScript будет выполнен:

<?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>
?>
0 голосов
/ 17 марта 2011

Когда-то я использовал действительно странный код для экранирования URL, но держу пари, что это можно сделать лучше, более того, это пока не распространяется на html specialchars, оно просто использовалось для сохранения URL в базе данных.

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;

}

...