Security: avoid challenge replay (#1148)
This commit is contained in:
parent
9a96b38435
commit
06c14f5972
|
@ -74,6 +74,9 @@ sub run {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$self->ott->updateToken( $token,
|
||||||
|
__ch => $data->{challenge} );
|
||||||
|
|
||||||
# Serialize datas
|
# Serialize datas
|
||||||
$data = JSON::to_json(
|
$data = JSON::to_json(
|
||||||
{
|
{
|
||||||
|
@ -83,6 +86,7 @@ sub run {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
my $tmp = $self->p->sendHtml(
|
my $tmp = $self->p->sendHtml(
|
||||||
$req,
|
$req,
|
||||||
'u2fcheck',
|
'u2fcheck',
|
||||||
|
@ -113,6 +117,21 @@ sub verify {
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->logger->debug("Get challenge: $challenge");
|
$self->logger->debug("Get challenge: $challenge");
|
||||||
|
|
||||||
|
unless ( $session->{__ch} and $session->{__ch} eq $challenge ) {
|
||||||
|
|
||||||
|
$self->userLogger->error("U2F challenge changes by user !!! $session->{__ch}/$challenge");
|
||||||
|
|
||||||
|
$req->error(PE_BADCREDENTIALS);
|
||||||
|
|
||||||
|
return $self->fail($req);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
delete $session->{__ch};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$self->logger->debug("Get signature: $resp");
|
$self->logger->debug("Get signature: $resp");
|
||||||
my $data = eval { JSON::from_json($resp) };
|
my $data = eval { JSON::from_json($resp) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
|
@ -129,6 +148,8 @@ sub verify {
|
||||||
$req->error(PE_BADCREDENTIALS);
|
$req->error(PE_BADCREDENTIALS);
|
||||||
return $self->fail($req);
|
return $self->fail($req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( not $crypter->setChallenge($challenge) ) {
|
if ( not $crypter->setChallenge($challenge) ) {
|
||||||
$self->logger->error(
|
$self->logger->error(
|
||||||
$@ ? $@ : Crypt::U2F::Server::Simple::lastError() );
|
$@ ? $@ : Crypt::U2F::Server::Simple::lastError() );
|
||||||
|
|
|
@ -112,6 +112,56 @@ sub getToken {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub updateToken {
|
||||||
|
|
||||||
|
|
||||||
|
my ( $self, $id, $k, $v ) = @_;
|
||||||
|
|
||||||
|
if ( $self->cache ) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
my $data;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unless ( $data = $self->cache->get($id) ) {
|
||||||
|
|
||||||
|
$self->logger->notice("Bad (or expired) token $id");
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
my $h = from_json( $data, { allow_nonref => 1 } );
|
||||||
|
|
||||||
|
$h->{$k} = $v;
|
||||||
|
$self->cache->set( $id, to_json($h), $self->timeout . ' s' );
|
||||||
|
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$self->p->getApacheSession( $id, $k => $v );
|
||||||
|
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sub setToken {
|
sub setToken {
|
||||||
my ( $self, $req, $info ) = @_;
|
my ( $self, $req, $info ) = @_;
|
||||||
$self->logger->debug('Prepare token');
|
$self->logger->debug('Prepare token');
|
||||||
|
|
Loading…
Reference in New Issue
Block a user