常量 FILTER_SANITIZE_STRING 已弃用
Constant FILTER_SANITIZE_STRING is deprecated
我已经安装了 PHP 8.1 并开始测试我的旧项目。我像这样使用过滤器 FILTER_SANITIZE_STRING
:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
现在我得到这个错误:
Deprecated: Constant FILTER_SANITIZE_STRING is deprecated
当我使用 FILTER_SANITIZE_STRIPPED
:
时也会发生同样的情况
Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated
我可以用什么代替它?
此过滤器的用途不明确。很难说它究竟是为了完成什么或何时应该使用它。由于其名称,它也与默认字符串过滤器混淆,而实际上默认字符串过滤器称为 FILTER_UNSAFE_RAW
。 PHP 社区决定不再支持使用此过滤器。
此过滤器的行为非常不直观。它删除了 <
和字符串末尾之间或直到下一个 >
之间的所有内容。它还删除了所有 NUL
字节。最后,它将 '
和 "
编码到它们的 HTML 实体中。
如果你想替换它,你有几个选择:
使用不进行任何过滤的默认字符串过滤器 FILTER_UNSAFE_RAW
。如果您对 FILTER_SANITIZE_STRING
的行为一无所知并且只想使用将为您提供字符串值的默认过滤器,则应使用此方法。
如果您使用此过滤器来防止 XSS 漏洞,请将其用法替换为 htmlspecialchars()
。不要对输入数据调用此函数。为了防止 XSS,您需要对输出进行编码!
如果您确切知道该过滤器的作用并且想要创建一个 polyfill,则可以使用正则表达式轻松完成。
function filter_string_polyfill(string $string): string
{
$str = preg_replace('/\x00|<[^>]*>?/', '', $string);
return str_replace(["'", '"'], [''', '"'], $str);
}
如果您打算将变量转换为安全的 html 字符串,您可以使用的最接近的常量是 FILTER_SANITIZE_FULL_SPECIAL_CHARS
根据我们的经验,FILTER_SANITIZE_STRING 对表单非常有用,因为当输入表单是单个文本输入时,我们找不到任何转义 HTML 的理由。
即使通过任何更改 JS 代码确实登陆了数据库,它的内容也是乱码,因为引号、单引号和 < > 被转换为 HTML 等价物。如果我们按原样回显字段内容,用户仍然是安全的,因为标签是乱码,不会运行。当然我们可能是错的,但我们没有遇到任何与过滤器直接相关的问题。
有些键盘没有正确的键盘语言,因此,他们在字段中输入的引号可能会或不会导致弯引号,这不利于将该字符串读回输入字段.
有人可能会争辩说,必须对特定字符串的输出进行转义,但是当您可以在将数据输入数据库之前清理字符串时,为什么还要多花两行代码来对 N 个不同输出的输出进行转义呢?
我们从未听说过 FILTER_SANITIZE_STRING 有防止 XSS 的目标,因为我们并没有完全将过滤器用于该特定任务。
在 link 中“不要尝试清理”没有提到使用 FILTER_SANITIZE_STRING。
他们给了我们一个例子(我稍微修改了一下):
$name ="Robert'); DROP TABLE users;";
$query = "SELECT * FROM users WHERE name = '{$name}'";
echo $query;
这产生:
SELECT * 来自用户名 = 'Robert');删除 TABLE 用户的
不出所料,这是一个 SQL 注入。
但是,如果我们过滤它:
$name = filter_var("Robert'); DROP TABLE users",FILTER_SANITIZE_STRING);
$query = "SELECT * FROM users WHERE name = '{$name}'";
echo $query;
这产生:
SELECT * 来自用户名 = 'Robert');删除 TABLE 用户的
我们将结束询问名为“Robert'
”的用户名;DROP TABLE users”并且查询将return没有结果。
我们确实希望 PHP 维护者能够回过头来看看过滤器的用处并保留它。但如果没有,那么我们只需要使用 polyfill
它可以很容易地替换为:
FILTER_UNSAFE_RAW
我已经安装了 PHP 8.1 并开始测试我的旧项目。我像这样使用过滤器 FILTER_SANITIZE_STRING
:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
现在我得到这个错误:
Deprecated: Constant FILTER_SANITIZE_STRING is deprecated
当我使用 FILTER_SANITIZE_STRIPPED
:
Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated
我可以用什么代替它?
此过滤器的用途不明确。很难说它究竟是为了完成什么或何时应该使用它。由于其名称,它也与默认字符串过滤器混淆,而实际上默认字符串过滤器称为 FILTER_UNSAFE_RAW
。 PHP 社区决定不再支持使用此过滤器。
此过滤器的行为非常不直观。它删除了 <
和字符串末尾之间或直到下一个 >
之间的所有内容。它还删除了所有 NUL
字节。最后,它将 '
和 "
编码到它们的 HTML 实体中。
如果你想替换它,你有几个选择:
使用不进行任何过滤的默认字符串过滤器
FILTER_UNSAFE_RAW
。如果您对FILTER_SANITIZE_STRING
的行为一无所知并且只想使用将为您提供字符串值的默认过滤器,则应使用此方法。如果您使用此过滤器来防止 XSS 漏洞,请将其用法替换为
htmlspecialchars()
。不要对输入数据调用此函数。为了防止 XSS,您需要对输出进行编码!如果您确切知道该过滤器的作用并且想要创建一个 polyfill,则可以使用正则表达式轻松完成。
function filter_string_polyfill(string $string): string { $str = preg_replace('/\x00|<[^>]*>?/', '', $string); return str_replace(["'", '"'], [''', '"'], $str); }
如果您打算将变量转换为安全的 html 字符串,您可以使用的最接近的常量是 FILTER_SANITIZE_FULL_SPECIAL_CHARS
根据我们的经验,FILTER_SANITIZE_STRING 对表单非常有用,因为当输入表单是单个文本输入时,我们找不到任何转义 HTML 的理由。
即使通过任何更改 JS 代码确实登陆了数据库,它的内容也是乱码,因为引号、单引号和 < > 被转换为 HTML 等价物。如果我们按原样回显字段内容,用户仍然是安全的,因为标签是乱码,不会运行。当然我们可能是错的,但我们没有遇到任何与过滤器直接相关的问题。
有些键盘没有正确的键盘语言,因此,他们在字段中输入的引号可能会或不会导致弯引号,这不利于将该字符串读回输入字段.
有人可能会争辩说,必须对特定字符串的输出进行转义,但是当您可以在将数据输入数据库之前清理字符串时,为什么还要多花两行代码来对 N 个不同输出的输出进行转义呢?
我们从未听说过 FILTER_SANITIZE_STRING 有防止 XSS 的目标,因为我们并没有完全将过滤器用于该特定任务。
在 link 中“不要尝试清理”没有提到使用 FILTER_SANITIZE_STRING。
他们给了我们一个例子(我稍微修改了一下):
$name ="Robert'); DROP TABLE users;";
$query = "SELECT * FROM users WHERE name = '{$name}'";
echo $query;
这产生:
SELECT * 来自用户名 = 'Robert');删除 TABLE 用户的
不出所料,这是一个 SQL 注入。
但是,如果我们过滤它:
$name = filter_var("Robert'); DROP TABLE users",FILTER_SANITIZE_STRING);
$query = "SELECT * FROM users WHERE name = '{$name}'";
echo $query;
这产生:
SELECT * 来自用户名 = 'Robert');删除 TABLE 用户的
我们将结束询问名为“Robert'
”的用户名;DROP TABLE users”并且查询将return没有结果。
我们确实希望 PHP 维护者能够回过头来看看过滤器的用处并保留它。但如果没有,那么我们只需要使用 polyfill
它可以很容易地替换为:
FILTER_UNSAFE_RAW