Security: avoid challenge replay (#1148)

This commit is contained in:
Christophe Maudoux 2018-04-17 19:09:23 +02:00
parent 9a96b38435
commit 06c14f5972
2 changed files with 71 additions and 0 deletions

View File

@ -74,6 +74,9 @@ sub run {
}
$self->ott->updateToken( $token,
__ch => $data->{challenge} );
# Serialize datas
$data = JSON::to_json(
{
@ -83,6 +86,7 @@ sub run {
}
);
my $tmp = $self->p->sendHtml(
$req,
'u2fcheck',
@ -113,6 +117,21 @@ sub verify {
}
$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");
my $data = eval { JSON::from_json($resp) };
if ($@) {
@ -129,6 +148,8 @@ sub verify {
$req->error(PE_BADCREDENTIALS);
return $self->fail($req);
}
if ( not $crypter->setChallenge($challenge) ) {
$self->logger->error(
$@ ? $@ : Crypt::U2F::Server::Simple::lastError() );

View File

@ -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 {
my ( $self, $req, $info ) = @_;
$self->logger->debug('Prepare token');