简体   繁体   中英

Security Topic - IS is_granted(ROLE_ADMIN) in TWIG enough?

I wanted to know if doing only a is_granted(ROLE_ADMIN) in twig is enough to secure a form.

I mean the form is available to anyone:
- some widget with choice selection are available to anyone to change.
- other widgets (widget about administration in the same form) are only displayed if ROLE_ADMIN is granted.

Is it enough to make it safe for administration stuff in this form to be only changed by the ROLE_ADMIN ? Or should I secure as well the controller.

(securing the controller would make me write much more, because right now I just have to do a flush(). then I would have to make many more tests for all the POST I got through the form request)

General recommendations

It depends on what you mean by security . And, it depends on your definition of secure enough as well.

Following questions might help:

  • Is it an internal-use application (such as a company-internal calendaring app where no sensitive data is stored or exposed)
  • Is it important to ensure security against purposely malformed requests (which I'd consider everytime the answer for the first question is 'yes'). But even if the answer to the former question is 'no', sometimes you can have malformed requests even in an internal calendaring app... it all depends on what you consider a security threat and what not. And, on your users.

If you don't secure it in the controller, then a user might submit an arbitrary POST request with the fields that are not displayed there, if she guesses the names of the fields correctly, or finds them somewhere. So, in my opinion, you should always double check for sanity.

You could:

  • ('pure' solution, more time-consuming) Separate the admin widgets by dynamically generating the form type depending on the users' privileges. Then you can always check for their existence in Twig, prior to the HTML generation. If you don't use the FormType, then I'd suggest you to do so - but you can dynamically add fields even if you build the whole form in the controller.
  • ('dirty' solution, but easy and fast to implement) Check for that role when handling the form submission in the controller (which you suggested).

And as an answer to your question in comments: "how can I simulate a POST to check if the token is enough to block POST field which are not actually display in my page." I can recommend you the Chrome Advanced Rest Client extension, if you use Google Chrome for development. I use it to test my forms with great success.

So, to sum it up, I think that the question is not clearly stated and cannot be answered generally. It all depends. But if you want a simple answer: it's not secure enough. Hiding something from one's eyes doesn't mean it's secure. Therefore...

Specific recommendations - a solution with a form event listener

This is how I would do it for maximum security (I use PHP 5.5 here, so ensure you have it or it needs some syntax tweaking).

In your FormType , register an event listener like such:

(...)

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);
}

Then, if a user is not an admin one, your form will not have these fields generated. Of course in Twig, if you render your widgets one by one, you should check for the field's existence prior to rendering them:

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

Or, using a shorter syntax with the newest Twig

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM