Php 为用户输入取消显示符号和是否安全?

Php 为用户输入取消显示符号和是否安全?,php,html,html-entities,sanitization,Php,Html,Html Entities,Sanitization,经过几个小时的bug搜索,我找到了我最讨厌的bug之一的原因 当用户在我的网站上键入消息时,他们可以使用纯文本和html实体对其进行标题 这意味着在某些情况下,用户将键入一个标题,其中包含常见的html实体图片,如此面。(°) 为了防止html注入,我使用htmlspecialchars();而令人烦恼的是,当稍后输出到页面上时,它会将图片转换为html实体格式 ( ͡° ͜ʖ ͡°) 我意识到这里的问题是标题被编码为上面

经过几个小时的bug搜索,我找到了我最讨厌的bug之一的原因

当用户在我的网站上键入消息时,他们可以使用纯文本和html实体对其进行标题

这意味着在某些情况下,用户将键入一个标题,其中包含常见的html实体图片,如此面。(°)

为了防止html注入,我使用htmlspecialchars();而令人烦恼的是,当稍后输出到页面上时,它会将图片转换为html实体格式

( ͡° ͜ʖ ͡°)
我意识到这里的问题是标题被编码为上面的示例,而htmlspecialchar,以及我想要做的和编码可能的html注入,正在将实体中的符号转换为

&. 
通过解开所有的符号,并将它们改回-,这解决了我的问题,脸就会如预期的那样出现


然而,我不确定这是否仍然是安全的恶意html。解码用户输入标题中的符号是否安全?如果没有,我如何着手解决这个问题?

没有直接的答案。您可能会将
脚本…
卸载到
中,并以故障告终,但代码似乎已被双重编码-可能在输入时一次,然后在输出到屏幕时再次编码。如果你能保证它是双重编码的,那么撤销其中一个应该是安全的

但是,最好的解决方案是将“原始”值保留在内存中,并对其进行清理/编码,以便输出到数据库、html、JSON等


所以-当您得到输入时,请对其进行清理,以获取您不想要的任何内容,但在此阶段不要将其转换为HTML或转义它或其他任何内容。将其转义到数据库中,并在输出到screen/xml等时对其进行html编码。

如果实体显示为文本,则可能会调用
htmlspecialchars()
两次

如果没有两次显式调用
htmlspecialchars()
,那么如果包含表单的页面使用过时的单字节编码(如Windows-1252),则可能会发生浏览器端自动转义。这种自动转义是正确表示特定单字节编码的字符集中不存在的字符的唯一方法。所有当前的浏览器(包括Firefox、Opera和IE)都这样做

确保您使用的是Unicode(特别是UTF-8)编码

要使用Unicode作为编码,请将
元素添加到包含表单的HTML页面的
标题部分。别忘了用UTF-8编码保存HTML页面本身。要在PHP中使用Unicode,通常使用Unicode就足够了。最后,像MySQL这样的数据库引擎很久以前就支持UTF-8了


作为一种临时解决方法,您可以通过将函数的第四个参数(
$double_encode
)设置为
false

来禁用对现有实体的重新编码。如果实体显示为文本,那么您可能会调用
htmlspecialchars()
两次。@Marat。当POST从输入中获取值时,它会自动编码更模糊的实体,如我提供的脸的鼻子和嘴。然而,它并没有对引号或尖括号之类的东西进行编码。这确实是我的问题,一些实体被编码了两次。不幸的是,除了再次编码之外,我不知道如何解决这个问题。这就是为什么我要问这个问题,看看是否有更好的方法。如果包含表单的页面使用的是过时的单字节编码(如Windows-1252),则可能会出现这种浏览器端自动转义。您确定使用的是Unicode(特别是UTF-8)?;-)我不确定。这是我第一个处理html实体的项目之一,对此我不太了解。我如何转换到使用unicode?克林特,请看我的答案。我相信这就是正在发生的事情。当我从POST收集输入值时,更模糊的实体已经被自动编码(我对php不是很有经验,也不知道为什么),但是像&、<和>这样的常见实体被留下来解码。这就是我使用双重编码的原因。有更好的方法吗?删除初始编码。你需要找出它发生的地方。根据另一条评论,我相信是浏览器自动转义了输入中的值。我怎样才能删除它?浏览器不会这样做。JavaScript可能会——因此,如果数据是由JavaScript处理的,那么请在那里进行检查。否则它将在PHP代码中。在php代码中查找“htmlspecialchars”、“hemlentities”或“preg_replace”调用。谢谢!添加false的工作非常有效。我将研究UTF-8。我在其他一些论坛上读到,这是没有必要的,需要大量的工作来实现它,有时它不值得花时间。在你看来,它值得转换吗?@Clint实际上,使用UTF-8并不难(在PHP中,请参阅)。试试看,你会喜欢的。;-)+1感谢Marat注意到编码可能是问题所在(您也可以将其放入数据库中,并小心JSON-编码是一个雷区)。回复:“是否值得转换”?-Marat说设置htmlspecialchars的第四个参数是一个“临时解决方案”,我同意这确实是一个逃避。除非你找到源头,否则你会陷入更深的深渊。因此,请检查字符集(正如Marat所说)或进行编码的代码-这确实值得修复并跟踪哪些变量已编码,哪些未编码。