In accordance with our security policy, we are releasing today symfony 1.2.6 to fix a security issue that has been spotted by the symfony core team.
This post contains the description of the vulnerability and the description of the changes we have made to fix it. The affected symfony versions are all symfony 1.2 releases and the 1.3 branch.
Description of the vulnerability
The new admin generator can be configured via the generator.yml
configuration file. To create or modify an existing record, the admin
generator uses the form associated with the model class. This form can be
customized via the form
, edit
, and new
sections.
The display
entry of these sections allows the regrouping of form fields in
field sets. If you use this option to hide some fields defined in the form
class, and if these fields are not required, you might think it works
correctly. It does not. As
stated in the documentation,
you must list all form fields in the display
section. The correct way to
hide form fields in the admin generator is to unset them from the form class
itself:
[php]
class ArticleForm extends BaseArticleForm
{
public function configure()
{
// safely remove the is_admin field from the form
unset($this['is_admin']);
}
}
If not, a malicious user can potentially inject values for fields for which he
does not have the right for (as it won't be caught by the security measure
implemented by the allow_extra_fields
setting of the form).
To sum up, you are potentially affected if you use the new admin generator
bundled with symfony 1.2 (Propel or Doctrine) and have removed some form
fields in the display
entry of the generator.yml
form sections without
unsetting them in the corresponding form class.
Resolution
As of symfony 1.2.6, the new admin generator prevents such a problem by automatically unsetting the hiding fields from the form object (but not the hidden fields).
If you are affected, you can fix the problem by:
Upgrading to symfony 1.2.6;
Applying the patch for symfony 1.2.5
Editing your form classes and unsetting the fields you want to hide from the edit or new form (as show above in the small example).
The symfony 1.2.6 release is based on the 1.2.5 version and only contains the security fix as a difference. All other pending changes have been moved to the upcoming 1.2.7 release.
When was this vulnerability introduced? We didnt have this problem earlier. do we?
Thanks!
@Pablo: As I said in the post, this vulnerability exists since symfony 1.2.0.
.. but if you secured your admin generator modules by credentials and do not grant "normal users" these credentials this should not be a big issue
I posted something of a similar nature in the forums regarding Symfony 1.0. Something along the lines of disabling fields, but not checking serverside.
As others have said, this exists in the admin generator, so it's not a massive vulnerability. Either way, it's good that it's been plugged!
@Matthias: The number of affected websites can be relatively small, the security issue is also quite difficult to exploit as admin generated modules are most of the time secured; but there is nonetheless a possibility of an exploit, that's why we have released a fix as soon as possible. The goal of the symfony framework is to be as secure as possible.
But this will stop us from being able to do the following very useful trick....
form has fields 'first_name' & 'last_name'
display [_name]
_name partial combines 'first_name' & 'last_name' in one row.
Or am I missing something??
@Fabien: I just tried to avoid panic.. I know that symfony is secure. That is one reason why I use it. Thanks for the fix!
It reminds me a post fabien wrote some time ago, regarding a similar security problem with ror. Unfortunately, i can't find it...
So this does not apply to applications not using the admin generator? Can these wait with update for the 1.2.7 release?
@cschnell: right, if you don't use the admin generator, you are not affected in any way. So, no need to upgrade at all.
i guess the code to unset should be
unset($this->widgetSchema['is_admin']); instead of unset($this['is_admin']);