【发布时间】:2019-04-25 16:38:48
【问题描述】:
当在表单上接收用户输入时,我想检测“用户名”或“地址”等字段是否不包含在 XML(RSS 提要)或 (X)HTML(显示时)中具有特殊含义的标记。
那么,在 HTML 和 XML 上下文中,检测输入的输入是否不包含任何特殊字符的正确方法是?
if (mb_strpos($data, '<') === FALSE AND mb_strpos($data, '>') === FALSE)
或
if (htmlspecialchars($data, ENT_NOQUOTES, 'UTF-8') === $data)
或
if (preg_match("/[^\p{L}\-.']/u", $text)) // problem: also caches symbols
我是否遗漏了其他任何内容,例如字节序列或其他棘手的方法来获取诸如“javascript:”之类的标记标签?据我所知,所有XSS and CSFR attacks 都需要< 或> 围绕值才能让浏览器执行代码(至少来自Internet Explorer 6 或更高版本) - 这是正确的吗?
我不是在寻找减少或过滤输入的东西。我只是想在 XML 或 HTML 上下文中找到危险的字符序列。 (strip_tags() 非常不安全。正如手册所说,它不会检查格式错误的 HTML。)
更新
我想我需要澄清一下,有很多人误认为这个问题是关于通过“转义”或“过滤”危险字符的基本安全问题。这不是那个问题,而且给出的大多数简单答案无论如何都不能解决这个问题。
更新 2:示例
- 用户提交输入
if (mb_strpos($data, '<') === FALSE AND mb_strpos($data, '>') === FALSE)- 我保存了
现在数据在我的应用程序中,我用它做两件事 - 1) 以 HTML 之类的格式显示 - 或 2) 在格式元素中显示以进行编辑。
第一个在 XML 和 HTML 上下文中是安全的
<h2><?php print $input; ?></h2>'
<xml><item><?php print $input; ?></item></xml>
第二种形式比较危险,但应该还是安全的:
<input value="<?php print htmlspecialchars($input, ENT_QUOTES, 'UTF-8');?>">
更新 3:工作代码
您可以下载 the gist I created 并将代码作为文本或 HTML 响应运行,以了解我在说什么。这个简单的检查通过了http://ha.ckers.org XSS Cheat Sheet,但我找不到任何可以做到的东西。 (我忽略了 Internet Explorer 6 及以下版本)。
我开始了另一项赏金活动,奖励那些在这种方法上存在问题或在实施过程中存在弱点的人。
更新 4:询问 DOM
这是我们想要保护的 DOM - 那么为什么不直接问它呢? Timur's answer 导致:
function not_markup($string)
{
libxml_use_internal_errors(true);
if ($xml = simplexml_load_string("<root>$string</root>"))
{
return $xml->children()->count() === 0;
}
}
if (not_markup($_POST['title'])) ...
【问题讨论】:
-
你也可以看看php的strip_tags()函数
-
strip_tags() 非常不安全。正如手册所说,它不检查 malformed HTML.
-
谢谢@webarto,但就像我说的,我不是要修复 HTML。只需阻止浏览器将字符串视为标记即可。
-
@baudday,我不想清理代码。我只是想找出在 HTML 或 XML 上下文中使用时可能有问题的值。我不想过滤或删除任何内容。
标签: php html input xss sanitization