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

Tobias Sjösten
Contributed by Tobias Sjösten in #9782

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

Joshua Thijssen
Contributed by Joshua Thijssen in #13342

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

Sarah Khalil Maxime Steinhausser
Contributed by Sarah Khalil and Maxime Steinhausser in #12818 and #14032

Symfony 2.7 introduces a new command called security:encode-password which allows to encode plain passwords for the given user class:

Symfony encoded password

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.

Published in #Living on the edge