防止Symfony内的“叠加表格”

Overposting a form is a common way of manipulating data / hacking a site. The cause for that possible security problem is the Form/Model Binder, that automatically binds a Form to an object. Within ASP.NET, I know how to protect against these sort of attacks.

We have a User Model, with the following fields: ID, Firstname, Lastname, Password. I want the user to be able to change his Firstname and Lastname. As we know, this happens within Symfony (and ASP.NET MVC) with a Form/Model Binder, that takes the "names" of the forms and maps these values to the corresponding object fields.

Solution in ASP.NET, using the [Bind] expression on each "Post-Controller":

public async Task<ActionResult> Create([Bind(Include="FirstName,Lastname")] Employee employee)

How can I prevent this kind of attack within a Symfony application? How to tell the Model/Form binder, which post data should only be accepted / expected?

@Edit: This question intended to know how to solve this kind of problem when using a FormType for multiple usecases, e.g. for Creation and Edit of an employee. I know that in general, Symfony Form Component already checks if there are any additional fields.

class FooType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if ($options['type'] === 'edit') {
            $builder->add('editMe');
            //More edit me fields
        }

        $builder->add('createMe');
        //more create me fields            
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setRequired(array(
            'type'
        ));

        $resolver->setDefaults(array(
            'type' => 'create'
        ));
    }

    //For consistency 
    public function getName() 
    {
        return 'foo';
    }
}

There is no need for extra events since it would be an overkill.

Controller:

public function createFooAction(Request $request)
{
    $form = $this->createForm(new FooType(), new Foo());

    $form->handleRequest($request);
    if ($form->isValid() && $form->submitted()) {
        //flush form
    }

    return $this->render("AppBundle:Foo:create.html.twig", array(
        'form' => $form
    ));
}

public function editFooAction(Request $request, $id)
{
    $foo = ... //find($id)

    $form = $this->createForm(new FooType(), $foo, array(
        'type' => 'edit'
    ));

    $form->handleRequest($request);
    if ($form->isValid() && $form->submitted()) {
        //flush form
    }

    return $this->render("AppBundle:Foo:edit.html.twig", array(
        'form' => $form
    ));
}

Bonus

If you use the cookbook (read: normal) approach to symfony forms, you already have that protection, alongside with CSRF protecttion.

If you add an extra field to the request you will get the following error:

This form should not contain extra fields

Example Form:

class FooType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title');
        //Class Foo also has a text attribute
    }
}

You will create an edit or create form using the above class in your controller and only the fields added to the builder can be modified. This way Foo::$text can not be modified using the form.