In my project an User
can create a Customer
and assigning it zero or more Tag
. These entities have a relation with User
of course. This is done by a form that has a tag
field of entity type, filtered by current logged user:
$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);
}
))
;
And this is working fine. Looking at a generated HTML tags are rendered as checkboxes:
<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>
I'd like to investigate further about form tampering. In particular making a POST request from a trusted user adding customer%5Btags%5D%5B1%5D=1
, that is a tag with id
equal to 1 which exists but it has been created by another user. Attacker user is creating an customer with a tag created by another user:
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
.. and seems there is some sort of control that prevents this. Result is 200 OK
(should be a 302
in case of success) without any error and form is rendered again. Of course entity is not persisted.
Actual question is: how Symfony 2 protect from this kind of form "tampering" attacks? A possible explanation is the it checks that submitted tags exist inside the collection returned by the form builder. But a reference is needed...
EDIT: even disabling CSRF protection the result is the same. By the way i was passing a valid token and CSRF is intended to protect from other types of attacks.