Избыточное размещение формы является распространенным способом манипулирования данными / взлома сайта.
Причиной этой возможной проблемы безопасности является привязка формы / модели, которая автоматически связывает форму с объектом. В ASP.NET я знаю, как защитить себя от подобных атак.
У нас есть модель пользователя со следующими полями: ID, Имя, Фамилия, Пароль. Я хочу, чтобы пользователь мог изменить свое имя и фамилию.
Как мы знаем, это происходит в Symfony (и ASP.NET MVC) с привязкой Form / Model, которая берет «имена» форм и сопоставляет эти значения с соответствующими полями объекта.
Решение в ASP.NET с использованием выражения [Bind] на каждом «пост-контроллере»:
public async Task<ActionResult> Create([Bind(Include="FirstName,Lastname")] Employee employee)
Как я могу предотвратить подобные атаки в приложении Symfony? Как сообщить связующему модели / формы, какие данные должны приниматься / ожидаться?
@Редактировать:
Этот вопрос предназначен для того, чтобы узнать, как решить эту проблему при использовании FormType для нескольких вариантов использования, например, для создания и редактирования сотрудника. Я знаю, что в общем случае Symfony Form Component уже проверяет наличие дополнительных полей.
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';
}
}
Нет необходимости в дополнительных мероприятиях, так как это было бы излишним.
контроллер:
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
));
}
Если вы используете подход поваренной книги (читай: обычный) к формам Symfony, у вас уже есть такая защита, наряду с защитой CSRF.
Если вы добавите дополнительное поле к запросу, вы получите следующую ошибку:
Эта форма не должна содержать дополнительных полей
Пример формы:
class FooType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('title');
//Class Foo also has a text attribute
}
}
Вы создадите форму редактирования или создания с использованием вышеуказанного класса в вашем контроллере, и только поля, добавленные в конструктор, могут быть изменены. Таким образом, Foo :: $ text нельзя изменить с помощью формы.