New in Symfony 2.7: Security Improvements

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

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

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

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.

Comments

It seems that all links on avatar in the "contributed by" section goes to /fabpot or /burgov.
Interesting ;-)
@Jeremy thanks for the heads up and sorry for that. It's fixed now.
@Javier: I'm glad to read this blog post. But it seems like the wrong PR is linked (#13985 instead of #14032) about the new command. :)
@Maxime you are right. I'm really sorry! It's fixed now.

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.