Symfony2 and Impersonating Users, a Heads Up

Recently I was working on a project in which it admins were able to impersonate other users.  It’s a fairly easy task to add to Symfony2, merely adding a switch_user reference to your firewall can make it possible, consult the Symfony docs for more on that.  One thing I noticed was that every now and then when testing I would get weird errors after switching between multiple users, however it didn’t always happen.  After some digging around, it turns out when you switch user it does not clear that sessions attributes, ie if you set attribute ‘hello’ to value ‘world’ it would persist after you’ve impersonated another user.  This caused a few issues as on this application we used the session to store a few things like which set of database connections you currently use.

After looking at the SecurityBundle configuration setup it was clear that there wasn’t any options to have it clear all session attributes on switch user.  At this point it was clear I needed to use an event listener as the firewall dispatched the SwitchUserEvent when a user successfully switched user.  Below is an excerpt from my services.yml
This makes it so that it will call the following code on a successful impersonation of a user:

It’s as simple as that, you can get the actual user by calling $event->getTargetUser(). Long story short, the session can have some tainted values when using switch user as all attributes are not cleared.

Posted In: Symfony, Tips n' Tricks

Tags: , , , , ,

  • Konrad Podgórski

    Thanks, good to know. I have 2 more things to add

    Storing anything other than some notice/error messages that are cleared in next requests is generally bad idea

    One exception that I can think of is ecommerce site where user add products to shopping cart before creating account (or signin in). But even in this case storing whole products list is poor practice, instead you should store only cart id, persist it to database and immediately after login reference it to the user.

  • I agree usually things should be persisted to the database. In my case it was just an id of a connection that the user was currently viewing for only that session.

    However, to your point storing lists in the session it definitely can be a bad practice. We’ve seen people before try to store some largest lists in the session and they get truncated/corrupt the session due to the size.