安全主题 - IS is_granted(ROLE_ADMIN)在TWIG中足够多了吗?

时间:2015-02-24 11:37:07

标签: php forms symfony

我想知道在twig中只做一个is_granted(ROLE_ADMIN)是否足以保护表单。

我的意思是表格可供任何人使用:
- 任何人都可以选择一些具有选择选项的小部件 - 只有在授予ROLE_ADMIN的情况下,才会显示其他小部件(相同表单中的管理小部件)。

是否足以使此表单中的管理内容只能由ROLE_ADMIN更改?或者我应该保护控制器。

(保护控制器会让我写得更多,因为现在我只需要做一个flush()。然后我必须为通过表单请求获得的所有POST做更多的测试)

1 个答案:

答案 0 :(得分:1)

一般建议

这取决于安全性的含义。而且,这取决于您对足够安全的定义。

以下问题可能有所帮助:

  • 是内部使用的应用程序(例如公司内部日历应用程序,其中不存储或暴露敏感数据)
  • 确保安全性以防止故意格式错误的请求(每次第一个问题的答案为“是”时,我都会考虑这一点)。但即使前一个问题的答案是“不”,有时即使在内部日历应用程序中,您也可能会出现格式错误的请求......这一切都取决于您认为的安全威胁和什么不是。并且,对您的用户。

如果您没有在控制器中保护它,那么如果用户正确猜出字段的名称,或者在某处找到它们,则用户可能会提交任意POST请求,其中包含未显示的字段。因此,在我看来,你应该经常仔细检查是否理智。

你可以:

  • ('纯'解决方案,更耗时)通过根据用户权限动态生成表单类型来分隔管理窗口小部件。然后,您可以在生成HTML之前始终在Twig中检查它们是否存在。如果您不使用FormType,那么我建议您这样做 - 但即使您在控制器中构建整个表单,也可以动态添加字段。
  • ('脏'解决方案,但实施简单快捷)在控制器(您建议)处理表单提交时检查该角色。

作为对评论中问题的回答:“我如何模拟POST以检查令牌是否足以阻止POST字段,而这些字段实际上并未显示在我的页面中。”如果您使用Google Chrome进行开发,我可以向您推荐Chrome Advanced Rest Client扩展程序。我用它来测试我的表格非常成功。

所以,总结一下,我认为这个问题没有明确说明,一般都无法回答。这完全取决于。但如果你想要一个简单的答案:它不够安全。隐藏一个人的眼睛并不意味着它是安全的。因此...

具体建议 - 具有表单事件侦听器的解决方案

这就是我为了最大程度的安全而做的事情(我在这里使用PHP 5.5,所以确保你有它或者它需要一些语法调整)。

FormType中,注册一个类似的事件监听器:

(...)

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('product_id', 'hidden');

    (...)

    $dynamicFieldCreatorFunc = function (FormEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();

        if ($this->getContainer()->get('security.context')->isGranted('ROLE_ADMIN'))
        {
            $form->add('admin_field', 'choice', [
                'choices' => [1 => 'Choice 1', 2 => 'Choice 2'],
            ]);
        }
    };

    $builder->addEventListener(FormEvents::PRE_SET_DATA, $dynamicFieldCreatorFunc);
    $builder->addEventListener(FormEvents::PRE_SUBMIT, $dynamicFieldCreatorFunc);
}

然后,如果用户不是管理员,则表单不会生成这些字段。当然在Twig中,如果逐个渲染小部件,则应在渲染之前检查该字段是否存在:

{% if form.admin_field is defined %}
    {{ form_widget(form.admin_field) }}
{% endif %}

或者,使用较短的语法和最新的Twig

{% form.admin_field is defined ? form_widget(form.admin_field) }}