【发布时间】: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()。