在我的项目中,User
可以创建Customer
并将其分配为零或更多Tag
。当然,这些实体与User
有关系。这是由tag
字段entity type的表单完成的,由当前登录用户过滤:
$user = $this->securityContext->getToken()->getUser();
$builder
->add('tags', 'meta_selector', array(
'label' => 'Tag',
'class' => 'Acme\HelloBundle\Entity\Tag',
'property' => 'select_label',
'query_builder' => function(EntityRepository $er) use($user) {
$qb = $er->createQueryBuilder('t');
return $qb
->where($qb->expr()->eq('t.user_id', ':user')
->orderBy('t.name')
->setParameter('user', $user);
}
))
;
这很好用。查看生成的HTML标记将呈现为复选框:
<div class="controls">
<label class="checkbox">
<input type="checkbox" value="2" name="customer[tags][2]"
id="customer_tags_2"> A Tag
</label>
<label class="checkbox">
<input type="checkbox" value="3" name="customer[tags][3]"
id="customer_tags_3"> Another Tag
</label>
</div>
我想进一步调查表格篡改。特别是从可信用户添加customer%5Btags%5D%5B1%5D=1
发出POST请求,该id
是POST http://localhost/Symfony2/web/app_dev.php/app/customers/new HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/Symfony2/web/app_dev.php/app/customers/new
Cookie: PHPSESSID=3avu1a2a1eufthr5tdftuhrnn7; hl=it
Content-Type: application/x-www-form-urlencoded
Content-Length: 276
customer%5Bfirst%5D=fake&customer%5Blast%5D=fake&customer%5Bgender%5D=m&customer%5Bbirthday%5D=&customer%5Bemail%5D=&customer%5Bmobile%5D=&customer%5Baddress%5D=&customer%5Bcountry%5D=IT&customer%5Btags%5D%5B1%5D=1&customer%5B_token%5D=455783fa2f866677669c9034a90554b9f75d68b4
等于1的标记,但是它已由另一个用户创建。攻击者用户正在使用其他用户创建的标记创建客户:
200 OK
..似乎有某种控制可以防止这种情况发生。结果为302
(如果成功,则应为{{1}}),不会出现任何错误,并且会再次呈现表单。当然实体不会持久存在。
实际问题是:Symfony 2如何防止这种形式的“篡改”攻击?可能的解释是它检查提交的标签是否存在于表单构建器返回的集合中。但需要参考......
编辑:即使禁用CSRF保护,结果也是一样的。顺便说一句,我传递了一个有效的令牌,CSRF旨在防止其他类型的攻击。</ p>
答案 0 :(得分:2)
您的问题的答案可以很容易地解释。每个选择字段(以及实体类型是选择类型的特化)都有一个选项列表。对于每个选择,该字段都了解
Tag
实例)Tag
的属性)当您提交表单时,选择字段在此列表中查找哪个模型表示与提交的视图表示匹配。如果找不到任何内容,则该字段仍未分配。
此逻辑的代码可以在类ChoiceList及其后代中找到,在您的情况下EntityChoiceList。提交后,将执行方法getChoicesForValues(),该方法执行查找并针对速度进行优化。
答案 1 :(得分:0)
狂野猜测:启用了CSRF保护,您不会渲染错误。