【问题标题】:Why does filter_var() encode quotes differently than htmlentities()?为什么 filter_var() 对引号的编码与 htmlentities() 不同?
【发布时间】:2019-08-31 13:49:03
【问题描述】:

为什么 filter_var() 的 FILTER_SANITIZE_STRING 过滤器将单引号编码为',将双引号编码为",而 htmlentities() 将单引号编码为',而将双引号编码为"

代码示例:

<?php
$string = "Well that's \"different.\"";

echo "filter_var: ".filter_var($string, FILTER_SANITIZE_STRING)."\n";
echo "htmlentities: ".htmlentities($string, ENT_QUOTES)."\n";
echo "htmlspecialchars: ".htmlspecialchars($string, ENT_QUOTES)."\n";

输出:

filter_var: Well that&#39;s &#34;different.&#34; 
htmlentities: Well that&#039;s &quot;different.&quot; 
htmlspecialchars: Well that&#039;s &quot;different.&quot;

【问题讨论】:

  • 你当然可以向 Rasmus Lerdorf 提出同样的问题。
  • 最后它们是等价的,所以……
  • @deceze 这是基于意见的吗?这个不知道怎么回答。
  • @deceze True,除非您要对以两种不同方式编码的字符串进行字符串比较。
  • @mick 这可能是有原因的。我猜filter_* 的实现非常通用,将不在某个白名单中的任何内容替换为其字符代码;而html* 更擅长 HTML 并且知道所有别名。

标签: php encoding html-entities sanitization filter-var


【解决方案1】:

这是因为filter 扩展与HTML 处理无关。它不使用 HTML 实体转换表。这只是基于 ASCII 值的愚蠢编码。

  • " 在 ASCII 中是 34
  • ' 在 ASCII 中是 39

这同样适用于 filter 扩展转换为 HTML 编码形式的任何其他字符。它采用十进制的 ASCII 数值,前置 &amp;# 并附加 ;。而已!它简单而高效,即使它不是很正确。

无意冒犯任何人,但是将这个扩展用于任何与 HTML 相关的东西是一个相当愚蠢的想法。常量 FILTER_SANITIZE_STRING 现在已弃用,它将在 PHP 的未来版本中删除。存在一个过滤器FILTER_SANITIZE_FULL_SPECIAL_CHARS,它只是htmlspecialchars() 的一个包装器,但我想不出任何理由在简单的htmlspecialchars() 函数上使用它。

其中一些过滤器是 PHP 懒惰时代的遗留物。开发人员使用了诸如魔术引号之类的惰性安全方法,这些方法没有提供足够的安全性,并且经常导致更多的混乱。这些 HTML 过滤器在创建时考虑了相同的惰性方法。提供一些东西来缓解 XSS 总比没有好。但是,这绝对不再是推荐的做法。请使用适当的函数正确格式化输出以避免 XSS,而不是依赖过滤器进行清理。

【讨论】:

    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    相关资源
    最近更新 更多