我有一个PHP Web应用程序。我不想让用户将HTML发布到我的网站。
如果我只是在保存到我的数据库之前对所有数据运行strip_tags
(),那么strip_tags
()是否足以阻止XSS?
我问,因为如果XSS被阻止,我不清楚阅读documentation of strip_tags。浏览器似乎存在一些错误,允许<0/script>
(是的,零)作为有效的HTML。
UPDATE
我意识到我可以简单地在所有输出数据上运行htmlspecialchars
;但是,我的想法是 - 因为我不想首先允许HTML,所以在保存到我的数据库之前,一劳永逸地清理我的数据会更容易(并且在学术上更好),然后每次都要担心如果数据是安全的,我输出数据。
我强烈反对它“学术上更好”。
&
进行转义。strip_tags()
不足以保护属性中的值,例如,<input value="$foo">
可能被$foo
= " onfocus="evil()
利用(没有<
,需要>
!)因此,正确的解决方案是根据您生成的语言要求来转义数据。如果您有纯文本并且正在生成HTML,则应使用htmlspecialchars()
等将文本转换为HTML。在生成电子邮件时,应将文本转换为可引用的可打印格式,依此类推。
strip_tags
本身不够,因为它删除了完全有效的非HTML内容。例如:
<?php
echo strip_tags("This could be a happy clown *<:) or a puckered face.\n");
....
echo strip_tags("Hey guys <--- look at this!\n");
将输出:
This could be a happy clown *
和:
Hey guys
最初的<
之后的一切都被删除了。最终用户非常讨厌!不接受保留的HTML字符将是一个不好的举动。当与HTML内联使用时,这些字符需要使用htmlentities
或类似函数进行转义。
你需要更高级的东西strip_tags
- HTML Purifier工作得很好,并允许用户使用HTML保留字符。
正如其他人所提到的,你可以使用strip_tags
和htmlspecialchars
的组合来保护自己免受XSS攻击。
关于strip_tags
的一个坏处是,它可能会删除用户不会期望的无害内容。我看到技术人员写的东西像:<edit> foo </edit>
,他们完全希望这些标签被视为原样。此外,我看到“正常”的人甚至做了像<g>
这样的“咧嘴笑”。同样,如果没有出现,他们会认为这是一个错误。
所以个人而言,我避免使用strip_tags
而不是我自己的解析器,它允许我明确启用某些安全的HTML标签,属性和CSS,显式禁用不安全的标签和属性,并将任何其他特殊字符转换为无害的版本。因此,文本总是被视为人们所期望的。
如果我没有那个解析器,我只需使用htmlspecialchars
安全地编码文本。
它应该,我以前从未听说过那个0技巧。但你可以随时做strip_tags
然后htmlspecialchars
只是为了安全。好的做法是在您的应用程序上自行测试,因为您知道可以尝试输入和测试的数据类型,看它是否会破坏它。只需搜索XSS漏洞利用方法,并将其用于测试数据。我会至少每周检查一次新的漏洞,并不断测试你的脚本是否有新的漏洞。
strip_tags()
可以提供帮助,但它不是防弹的。由于它没有验证HTML的剥离,一些聪明的人会发现一个HTML构造(损坏或其他)被剥离,但仍然会导致令人讨厌的事情。但就目前而言,它应该处理大多数被抛出的东西。只是不要认为这将永远是真的。
同样,如果您允许任何标记通过“允许标记”参数传递,那么将允许通过任何特定于JavaScript的属性,例如针对这些特定标记的onclick。
需要帮助将html视为文档中的纯文本?需要echo
属性的价值而不是像<input value="<?php echo '" onkeydown="alert("XSS")'; ?>" />
那样的XSS攻击吗?
echo htmlentities('<p>"..."</p>');
// result: <p>"..."</p>
没有strip_tags()
需要,因为这个功能已经用<
和>
实体替换<
和>
。
您可能会问
htmlentities()
和htmlspecialchars()
有什么区别?
好吧,htmlentities()
将编码具有HTML实体等效的任何字符,
而htmlspecialchars()
只编码一小部分最有问题的人物。