Security: avoid challenge replay (#1148)

This commit is contained in:
Xavier Guimard 2018-04-17 17:27:49 +02:00
parent c81757152f
commit 797fa5b5c3
2 changed files with 29 additions and 1 deletions

View File

@ -9,6 +9,7 @@ use strict;
use Mouse;
use JSON qw(from_json to_json);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_BADCREDENTIALS
PE_ERROR
PE_OK
PE_SENDRESPONSE
@ -58,7 +59,9 @@ sub run {
return PE_U2FFAILED if ( $res == 0 );
my $challenge = $req->datas->{crypter}->authenticationChallenge;
my $tmp = $self->p->sendHtml(
$self->ott->updateToken( $token,
__ch => JSON::from_json($challenge)->{challenge} );
my $tmp = $self->p->sendHtml(
$req,
'u2fcheck',
params => {
@ -88,6 +91,12 @@ 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};
if ( not $req->datas->{crypter}->setChallenge($challenge) ) {
$self->logger->error(
$@ ? $@ : Crypt::U2F::Server::Simple::lastError() );

View File

@ -112,6 +112,25 @@ 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');