Fix wildcarded VHost & improve unit test (#2386)

This commit is contained in:
Christophe Maudoux 2020-11-17 21:15:58 +01:00
parent dfc68f9f98
commit df99148b68
2 changed files with 64 additions and 22 deletions

View File

@ -320,17 +320,23 @@ sub check {
$self->_createArray( $req, $attrs, $savedUserData ) );
}
if ( $self->p->checkXSSAttack( 'CheckUser URL', $url ) ) {
$url = '';
$auth = 'VHnotFound';
}
# Check if user is allowed to access submitted URL and compute headers
if ( $url and %$attrs ) {
# Check url format
$url = $self->_urlFormat($url);
my $originalUrl;
( $url, $originalUrl ) = $self->_resolveURL($url);
# User is allowed ?
$self->logger->debug(
"checkUser requested for user: $attrs->{ $self->{conf}->{whatToTrace} } and URL: $url"
"checkUser requested for user: $attrs->{ $self->{conf}->{whatToTrace} } and URL: $url | alias: $originalUrl"
);
$auth = $self->_authorization( $req, $url, $attrs );
$auth = $self->_authorization( $req, $originalUrl, $attrs );
if ( $auth >= 0 ) {
$auth = $auth ? "allowed" : "forbidden";
$self->logger->debug(
@ -338,7 +344,8 @@ sub check {
. "$auth to access to $url" );
# Return VirtualHost headers
$array_hdrs = $self->_headers( $req, $url, $attrs, $savedUserData );
$array_hdrs =
$self->_headers( $req, $originalUrl, $attrs, $savedUserData );
}
else {
$auth = 'VHnotFound';
@ -352,17 +359,14 @@ sub check {
# TODO:
my $params = {
PORTAL => $self->conf->{portal},
MAIN_LOGO => $self->conf->{portalMainLogo},
SKIN => $self->p->getSkin($req),
LANGS => $self->conf->{showLanguages},
MSG => $msg,
ALERTE => ( $msg eq 'checkUser' ? 'alert-info' : 'alert-warning' ),
LOGIN => $user,
URL => (
$self->p->checkXSSAttack( 'URL', $url ) ? ""
: $url
),
PORTAL => $self->conf->{portal},
MAIN_LOGO => $self->conf->{portalMainLogo},
SKIN => $self->p->getSkin($req),
LANGS => $self->conf->{showLanguages},
MSG => $msg,
ALERTE => ( $msg eq 'checkUser' ? 'alert-info' : 'alert-warning' ),
LOGIN => $user,
URL => $url,
ALLOWED => $auth,
ALERTE_AUTH => $alert_auth,
HEADERS => $array_hdrs,
@ -370,7 +374,8 @@ sub check {
MACROS => $array_attrs->[1],
GROUPS => $array_attrs->[0],
TOKEN => (
$self->ottRule->( $req, {} ) ? $self->ott->createToken()
$self->ottRule->( $req, {} )
? $self->ott->createToken()
: ''
)
};
@ -380,7 +385,7 @@ sub check {
return $self->p->sendHtml( $req, 'checkuser', params => $params );
}
sub _urlFormat {
sub _resolveURL {
my ( $self, $url ) = @_;
$url = 'http://' . $url unless ( $url =~ m#^https?://[^/]*.*#i );
my ( $proto, $vhost, $appuri ) = $url =~ m#^(https?://)([^/]*)(.*)#i;
@ -390,7 +395,10 @@ sub _urlFormat {
$vhost =~ s/:\d+$//;
$vhost .= $self->conf->{domain} unless ( $vhost =~ /\./ );
return lc("$proto$vhost$port") . "$appuri";
my $originalVhost = $self->p->HANDLER->resolveAlias($vhost);
return ( lc "$proto$vhost$port$appuri",
lc "$proto$originalVhost$port$appuri" );
}
sub _userData {

View File

@ -70,12 +70,47 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
or explain( $res->[2]->[0], 'trspan="checkUser"' );
count(1);
# Wildcarded VHost
$query =~ s/url=/url=http%3A%2F%2Fappli.example.llng/;
ok(
$res = $client->_post(
'/checkuser',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST checkuser'
);
ok( $res->[2]->[0] =~ m%<span trspan="allowed">%, 'Found allowed' )
or explain( $res->[2]->[0], 'trspan="allowed"' );
count(2);
( $host, $url, $query ) =
expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
# Bad VHost (checkXSS)
$query =~ s/url=http%3A%2F%2Fappli.example.llng/url=http%3A%2F%2Fappli'.example.llng/;
ok(
$res = $client->_post(
'/checkuser',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST checkuser'
);
ok( $res->[2]->[0] =~ m%<span trspan="VHnotFound">%, 'Found VHnotFound' )
or explain( $res->[2]->[0], 'trspan="VHnotFound"' );
count(2);
( $host, $url, $query ) =
expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
# Skipping time until the form token has expired
Time::Fake->offset("+5m");
$query =~ s/user=/user=rtyler/;
$query =~ s/url=/url=http%3A%2F%2Ftest1.example.com/;
ok(
$res = $client->_post(
'/checkuser',
@ -143,7 +178,6 @@ ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
or explain( $res->[2]->[0], 'Attribute Value uid' );
count(12);
$query =~ s/user=dwho/user=msmith/;
$query =~
s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Fmanager.example.com%2Fmanager.html/;