Ticker

6/recent/ticker-posts

How to encrypt session data in Symfony 4.x?

In Symfony 5.1 you can encrypt the contents of the session using a new MarshallingSessionHandler. But it is not available in Symfony 4.4 You have to make custom Session Handler to make sure your sensitive data will be encrypted in session.

Create new SessionHandler: app\src\Security\SessionHandler\MemcachedSessionHandler.php In the script bellow, i use Encryptor class, please follow the article to check it.

namespace App\Security\SessionHandler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use App\Security\Encryptor\Interfaces\EncryptorInterface;

/**
 * Memcached based session storage handler based on the Memcached class
 * provided by the PHP memcached extension.
 *
 * @see https://php.net/memcached
 *
 * Custom MemcachedSessionHandler for Biglobe
 */
class MemcachedSessionHandler extends AbstractSessionHandler
{
    private $memcached;

    /**
     * @var int Time to live in seconds
     */
    private $ttl;
    
    /**
     * @var string Key prefix for shared environments
     */
    private $prefix;

    /**
     * @var EncryptorInterface
     */
    private $encryptor;

    /**
     * @var ParameterBagInterface
     */
    private $params;

    /**
     * Constructor.
     *
     * List of available options:
     *  * prefix: The prefix to use for the memcached keys in order to avoid collision
     *  * expiretime: The time to live in seconds.
     *
     * @throws \InvalidArgumentException When unsupported options are passed
     */
    public function __construct(\Memcached $memcached, array $options = [], EncryptorInterface $encryptor, ParameterBagInterface $params)
    {
        $this->memcached = $memcached;

        $this->params = $params;

        $this->encryptor = $encryptor;
        
        if ($diff = array_diff(array_keys($options), ['prefix', 'expiretime'])) {
            throw new \InvalidArgumentException(sprintf('The following options are not supported "%s".', implode(', ', $diff)));
        }

        $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
        $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
    }

    /**
     * @return bool
     */
    public function close()
    {
        return $this->memcached->quit();
    }

    /**
     * {@inheritdoc}
     */
    protected function doRead($sessionId)
    {
        $enc_flag = $this->params->get('app.enc_flag');
        if ($enc_flag == true) {
            $data = $this->memcached->get($this->prefix.$sessionId) ?: '';

            if ($data != '')
                return $this->encryptor->decrypt($data);
            else
                return '';
        }
        else
            return $this->memcached->get($this->prefix.$sessionId) ?: '';
    }

    /**
     * @return bool
     */
    public function updateTimestamp($sessionId, $data)
    {
        $this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl);

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite($sessionId, $data)
    {
        $enc_flag = $this->params->get('app.enc_flag');
        if ($enc_flag == true)
            $data = $this->encryptor->encrypt($data);
        
        return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl);
    }

    /**
     * {@inheritdoc}
     */
    protected function doDestroy($sessionId)
    {
        $result = $this->memcached->delete($this->prefix.$sessionId);

        return $result || \Memcached::RES_NOTFOUND == $this->memcached->getResultCode();
    }

    /**
     * @return bool
     */
    public function gc($maxlifetime)
    {
        // not required here because memcached will auto expire the records anyhow.
        return true;
    }

    /**
     * Return a Memcached instance.
     *
     * @return \Memcached
     */
    protected function getMemcached()
    {
        return $this->memcached;
    }
}
And edit services.yaml

framework:
    # ...
    session:
        handler_id: App\Security\SessionHandler\MemcachedSessionHandler

Post a Comment

0 Comments