New in Symfony 2.7: Security Improvements
April 16, 2015 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
In addition to high impact changes and big features, the new Symfony versions always add tweaks and minor improvements across its codebase. In this article you'll learn about three small security-related changes that will improve your day-to-day productivity as developer.
Added a string representation for core users
Some developers add a magic __toString()
PHP method to their user entities to
define their string representation. This allows to use type casting such as
(string) $user
in the PHP application and {{ user }}
in the Twig templates.
However, in functional tests is common to use in-memory users to simplify tests.
The problem is that the core User class defined by Symfony doesn't include the
_toString()
method and all those type casts fail.
In Symfony 2.7 we decided to add a new method to the core User
class in order
to define its string representation. The code of this method is as simple as:
1 2 3 4 5 6
// src/Symfony/Component/Security/Core/User/User.php
public function __toString()
{
return $this->getUsername();
}
Improved the logout Twig extension
Symfony adds custom Twig extensions on top of Twig to integrate some components
into the templates. You probably know and use lots of these functions, filters
and tags, such as render()
, |trans
and {% form_theme %}
.
One of the least known and used extensions are the logout_path and logout_url functions, which generate the appropriate relative or absolute URL to logout from the given firewall:
1
<a href="{{ logout_path('firewall_name') }}">Close session</a>
In Symfony 2.7, the firewall name is optional. If you don't provide it, Symfony will automatically use the current firewall, whichever it is:
1
<a href="{{ logout_path() }}">Close session</a>
This minor change also allows to use this function in templates where you don't know the firewall name; for example in the templates of public third-party bundles.
Added a command to encode a password
Symfony 2.7 introduces a new command called security:encode-password
which
allows to encode plain passwords for the given user class:
What's the purpose of this command? First, when you use the in-memory user provider,
it's not trivial to encode the plain password before storing it in the security
configuration file. For example, when using the sha512
encoder, you had to
execute the following command to get the encoded password:
1
$ php -r '$pass = "..."; $salt = "..."; $iterations=5000; $salted = $pass.$salt; $digest = hash("sha512", $salted, true); for($i=1; $i<$iterations; $i++) { $digest = hash("sha512", $digest.$salted, true); } echo base64_encode($digest);'
In Symfony 2.7 you only have to execute the following:
1
$ php app/console security:encode-password 'plain_password' 'AppBundle\Entity\User'
By default the salt
value used by the password is generated automatically,
but you can add the --empty-salt
option to avoid adding it. However, you
cannot provide the salt
value yourself, because it's considered a bad security
practice (for example, in PHP7 the salt
option of the password_hash()
function is deprecated).
In addition to the in-memory user provider, this command can also be useful while developing the application, in case you need to manually check or update some encoded passwords stored in the database.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
Interesting ;-)