kreait / firebase-tokens-php

A PHP library to work with Firebase tokens
MIT License
223 stars 33 forks source link

issued at verification #1

Closed vecernik87 closed 7 years ago

vecernik87 commented 7 years ago

Hello, I faced an issue with tokens being randomly rejected due to IAT being in future. I figured out my hosting provider time is fraction of second behind from firebase server and this caused random failures (depending on user connection) of IAT verification because token was sometime issued practically at the same time as checked on server side. Temporary, I disabled IAT verification but it is obvious security hole. I was thinking - would you be interested in adding possibility to enable/disable verifications with flags or some config? I can imagine for example some sort of offset for IAT verification. Developers could add few secs tolerance so 1-2 seconds "in future" would not cause an issue.

jeromegamez commented 7 years ago

Hi @vecernik87,

as the token verification is handling a security issue, I would not feel comfortable with adding an option to weaken the security, even if I understand your pain. But: you can work around that by composing a new verifier in which you can check for the offset:

use Firebase\Auth\Token\Domain\Verifier;
use Firebase\Auth\Token\Exception\IssuedInTheFuture;
use Lcobucci\JWT\Token;

class TolerantVerifier implements Verifier
{
    /**
     * @var Verifier
     */
    private $base;
    /**
     * @var int
     */
    private $allowedOffset;

    public function __construct(Verifier $base, int $allowedOffset = 2)
    {
        $this->base = $base;
        $this->allowedOffset = $allowedOffset;
    }

    public function verifyIdToken($token): Token
    {
        try {
            return $this->base->verifyIdToken($token);
        } catch (IssuedInTheFuture $e) {
            $token = $e->getToken();
            if (...) {
                return $token;
            } else {
                throw $e;
            }
        }
    }
}

Then, in your code, you can work with it:

use Firebase\Auth\Token\Verifier as BaseVerifier;
use TolerantVerifier;

$verifier = new TolerantVerifier(new BaseVerifier($projectId));

I hope this helps!

:octocat: