使用 `json_encode` 防止 XSS 攻击
Posted
技术标签:
【中文标题】使用 `json_encode` 防止 XSS 攻击【英文标题】:Using `json_encode` to protect against XSS attacks 【发布时间】:2018-07-16 21:52:29 【问题描述】:我们最近通过安全分析器运行了我们的项目,并在代码中发现了需要对输入进行转义的区域。对于这个问题,我特别指的是跨站点脚本攻击。分析器建议使用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);
【问题讨论】:
我们需要更多信息来帮助您。您是否将数据输出到 HTML 中?在这种情况下,请使用htmlspecialchars()
。您是否将数据输出到 JavaScript 中?在这种情况下,请使用json_encode()
。
【参考方案1】:
要使用的编码取决于输出格式,因此您应该根据上下文使用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>
【讨论】:
【参考方案2】:有很多方法可以解决 XSS 漏洞。
如果有任何易受攻击的脚本保存在数据库中,请确保在显示时对其进行清理以确保它不会在前端执行,请使用以下函数清理输出:
htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
您可以添加 HTTP X-XSS-Protection 响应标头,这是 Internet Explorer、Chrome 和 Safari 的一项功能,可在检测到反射的跨站点脚本 (XSS) 攻击时阻止页面加载。
X-XSS-Protection "1; mode=block"
【讨论】:
以上是关于使用 `json_encode` 防止 XSS 攻击的主要内容,如果未能解决你的问题,请参考以下文章