我有一个 Symfony 项目,任何用户都可以注册一个帐户,然后创建一个page
,其形式包括一个字段content
。我想允许用户插入一些html(例如粗体文本,编号列表和其他一些元素),这是通过使用WYSIWYG编辑器 CKEditor 完成的。我创建了一个工具栏,仅在保存page
时允许将我选择的元素解析到数据库中。我可以使用以下方法显示此页面的内容:
{{ page.content | raw }}
这一切都按预期工作。但是,如果用户复制了请求后的内容,在某些JS或其他HTML中进行编辑,然后使用cURL进行发送,这将允许他们插入(有害的)代码。 我的问题是:如何防止这种情况发生?
我一直在阅读有关“卫生”或“净化”以清理用户输入的信息。像HTML Purifier这样的东西可以清理输出,我也考虑过通过为允许的元素创建一种“白名单树枝过滤器”来清理输出。最好在将输入保存到数据库之前先清理输入。我以为这是一个常见问题,但是我通常只通过转义所有HTML来找到有关如何清理输出的解决方案,在我看来,这也不是解决方案,因为我确实希望允许使用某些HTML。
答案 0 :(得分:3)
在用户使用here和symfony表单事件提交表单后,您可以在表单类型中进行净化:
use HTMLPurifier;
use HTMLPurifier_Config;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
$object = $event->getData();
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.AllowedElements', ['a', 'b', 'strong', 'ul', 'li', 'p', 'br']);
$config->set('Attr.AllowedFrameTargets', ['_blank']);
$purifier = new HTMLPurifier($config);
$content = $purifier->purify($object->getContent());
$object->setContent($content);
});
因此,在此示例中,用户内容被清除。 HTML.AllowedElements
定义了不应删除的元素。之后,该实体准备好被持久化到您的数据库中,而不会产生不良的html用户内容。
答案 1 :(得分:2)
诀窍是不要操纵用户输入。您应该验证/拒绝用户输入(例如:用户上传10GB的数据,或者用户启动了div元素,但并未结束),但请勿更改。它不会随处可见,也不会坐在数据库中感染任何人。
向用户显示页面时,即操作数据时。就像您说的那样,请转义您的字符:<表示<,&amp表示&,而&quot表示“。
我最近正在为此编程,而我所做的是使用XML解析器(luaexpat)。就您而言,您拥有具有XML解析器库的PHP。
通过XML解析器运行用户输入的HTML。如果出现任何未经授权的元素,则可以在输出中转义它们(<)或引发错误而不是内容。确保内容具有有效的XML也很好,这样用户就可以通过不关闭元素来弄乱页面的其余部分。
另一个想法是存储帖子类型的“版本标识符”。如果您决定添加更多功能/属性或切换到其他编码(例如BBCose),请在数据库中写一个便笺,以便更轻松地解码帖子。这是另一个原因,您不应该更改用户输入,而是更改用户输出,以防万一您先拒绝图像,然后再决定允许它。
也将白名单属性。不要让别人将JavaScript放入属性(例如<div onclick=“MaliciousCode();”>
)
请务必注意SQL注入攻击和HTML注入攻击。