使用`json_encode`来防止XSS攻击

时间:2018-02-06 18:35:16

标签: php security xss

我们最近通过安全分析器运行我们的项目,并在代码中找到需要转义输入的区域。对于这个问题,我特指的是Cross Site Scripting攻击。分析师建议使用htmlentitiesjson_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);
}

2 个答案:

答案 0 :(得分:3)

要使用的编码取决于输出格式,因此您应该使用json_encodehtmlentities,具体取决于上下文。这意味着需要在输出而不是输入上进行转义。然后添加或修改的任何字符都不会影响系统的其余部分。

写入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;