我们最近通过安全分析器运行我们的项目,并在代码中找到需要转义输入的区域。对于这个问题,我特指的是Cross Site Scripting攻击。分析师建议使用htmlentities
和json_encode
对输入进行整理,但我不相信json_encode
是正确的工具。在做了一些研究之后,我完全相信它从未打算以这种方式使用,在这方面的任何用处仅仅是一种副作用。以下是我逃避潜在XSS攻击的功能:
function escapeScriptTags($value)
{
return json_encode(htmlentities($value), JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS);
}
我遇到的问题是返回的字符串连接了双引号并附加到它上面。这会扭曲用户的输入并导致明显的问题。我找到的一个解决方法是:
function escapeScriptTags($value)
{
return trim(json_encode(htmlentities($value), JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS), '"');
}
因为引号被转义为\u0022
,所以删除的"
字符将是json_encode
添加的字符。
但正如我所说,我仍然不相信这是防止PHP中XSS攻击的正确方法。有没有更明确的方法来逃避用户输入以防止不改变用户输入的XSS攻击?
修改
在这个特殊的实例中,将输入的值写入HTML,但也有一些情况我写的是JavaScript。我的问题可能是没有一种通用的XSS保护方法。
EDIT2
所以似乎没有一种通用的方法。为了完整性以及需要此指导的任何人,这里是我的输入清理功能 - 包括SQL注入保护功能。任何批评或建议都非常受欢迎:
/**
* Escapes user input that is to be interpolated into JavaScript code to
* protect against Cross-Site Scripting (XSS) attacks.
*
* @param $value
* @return string
*/
function encodeJavaScriptString($value)
{
return json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS);
}
/**
* Escapes HTML tags to protect against Cross-Site Scripting (XSS) attacks.
*
* @param $value
* @return string
*/
function escapeScriptTags($value)
{
return htmlentities($value, ENT_QUOTES, 'UTF-8');
}
/**
* Escapes a string in order protect against a SQL injection attack. If `$like` is true,
* underscores and percent signs are also escaped for use in a`LIKE` clause.
*
* @param $value
* @param \mysqli $mysqli
* @param bool $like
* @return string
*/
function escapeSqlString($value, \mysqli $mysqli, $like = false)
{
return $like ? addcslashes($mysqli->real_escape_string($value), '%_')
: $mysqli->real_escape_string($value);
}
答案 0 :(得分:3)
要使用的编码取决于输出格式,因此您应该使用json_encode
或htmlentities
,具体取决于上下文。这意味着需要在输出而不是输入上进行转义。然后添加或修改的任何字符都不会影响系统的其余部分。
写入JavaScript变量时,双引号成为JavaScript字符串语法的一部分,不需要删除:
<script>
console.log(JSON.parse(<?= json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS) ?>));
</script>
写入html时,请仅使用htmlentities
:
<div>
<?= htmlentities($value); ?>
</div>
答案 1 :(得分:1)
解决XSS漏洞的方法很多。
如果在数据库中保存了任何易受攻击的脚本,请确保在显示时通过清理它而不是在前端执行,使用下面的函数来清理输出:
htmlspecialchars($ string,ENT_QUOTES,&#39; UTF-8&#39;);
您可以添加HTTP X-XSS-Protection响应标头,这是Internet Explorer,Chrome和Safari的一项功能,可以在检测到反映的跨站点脚本(XSS)攻击时停止加载页面。
X-XSS-Protection&#34; 1;模式=块&#34;