Skip to content

Commit

Permalink
Item12952: Add security to configure ImageTest
Browse files Browse the repository at this point in the history
  • Loading branch information
gac410 committed Sep 23, 2014
1 parent afddc81 commit 256fa4e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 43 deletions.
94 changes: 55 additions & 39 deletions core/lib/Foswiki/Configure/ImageTest.pm
Original file line number Diff line number Diff line change
Expand Up @@ -33,86 +33,100 @@ use JSON ();
my @headers = ( "Cache-Control" => "no-cache", -expires => "-1d" );

sub _json {
my( $req, $res, $code, $data ) = @_;
my ( $req, $res, $code, $data ) = @_;
$res->header( -type => "application/json", -status => $code, @headers );
$res->print(JSON->new->allow_nonref->encode($data));
$res->print( JSON->new->allow_nonref->encode($data) );
return $res;
}

sub respond {
my $req = shift;

my $res = Foswiki::Response->new;

# Matches Configure::Dispatch
# SMELL: WTF does this have to be so complex?
# my $sid = $req->cookie('FOSWIKI_CONFIGURATION') || undef;
# if ( defined $sid && $sid =~ m/^([\w_-]+)$/ ) {
# $sid = $1;
# }
# else {
# return _json($req, $res, 403, "Forbidden, Not authorized by configure");
# }
# my $session =
# CGI::Session->load( Foswiki::Configure::SESSION_DSN, $sid,
# { Directory => File::Spec->tmpdir } )
# or die CGI::Session->errstr();
#
# unless( $req->auth_type
# || ( !$session->is_expired && !$session->is_new
# && ($session->param("_RES_OK") || $session->param("_PASSWD_OK")) ) ) {
# return _json($req, $res, 403, "Forbidden, Expired or no session");
# }
my ( $req, $res ) = @_;

if ( $Foswiki::cfg{isVALID} ) {

if ( defined $Foswiki::cfg{ConfigureFilter}
&& length( $Foswiki::cfg{ConfigureFilter} ) )
{
my $session = $Foswiki::Plugins::SESSION;
unless ( defined $session
&& $session->{user} =~ m/$Foswiki::cfg{ConfigureFilter}/ )
{
print STDERR
" $session->{user} doesn't match $Foswiki::cfg{ConfigureFilter} \n";
die "You must have special permission to use this interface.";
}
}
else {
# Check rights to use this interface - admins only
die
"You must be logged in as an administrator to use this interface."
unless Foswiki::Func::isAnAdmin();
}
}
else {
# Otherwise we must be bootstrapping - an inherently dangerous
# operation. TODO: check we can do this safely.
}

# Respond with embedded image

my $pinfo = $req->pathInfo;
unless( $pinfo && $pinfo =~ m,^/Web/Topic/(Img|Env)/(\w+), ) {
return _json( $req, $res, 403, "Forbidden, Incorrect path info " . ($pinfo || "none") );
unless ( $pinfo && $pinfo =~ m,^/Web/Topic/(Img|Env)/(\w+), ) {
return _json( $req, $res, 403,
"Forbidden, Incorrect path info " . ( $pinfo || "none" ) );
}

if( $1 eq "Env" ) {
my $data = { action => $2 };
if ( $1 eq "Env" ) {
my $data = { action => $2 };

my @cgivars = (

# CGI 'Standard'
qw/AUTH_TYPE CONTENT_LENGTH CONTENT_TYPE GATEWAY_INTERFACE/,
qw/PATH_INFO PATH_TRANSLATED QUERY_STRING REMOTE_ADDR/,
qw/REMOTE_HOST REMOTE_IDENT REMOTE_USER REQUEST_METHOD/,
qw/SCRIPT_NAME SERVER_NAME SERVER_PORT SERVER_PROTOCOL/,
qw/SERVER_SOFTWARE/,

# Apache/common extensions
qw/DOCUMENT_ROOT PATH_TRANSLATED REQUEST_URI SCRIPT_FILENAME/,
qw/SCRIPT_URI SCRIPT_URL SERVER_ADDR SERVER_ADMIN SERVER_SIGNATURE/,

# HTTP headers & SSL data
grep( /^(?:HTTP|SSL)_/, keys %ENV ),

# Other
qw/PATH MOD_PERL MOD_PERL_API_VERSION/,
);
);

foreach my $var (sort @cgivars) {
next unless( exists $ENV{$var} );
foreach my $var ( sort @cgivars ) {
next unless ( exists $ENV{$var} );
$data->{ENV}->{$var} = $ENV{$var};
}

$data->{'@INC'} = [ @INC ];
$data->{'@INC'} = [@INC];
my @gids;
eval {
@gids = map { lc getgrgid($_) } split( ' ', $( );
};
if( $@ ) {
@gids = ( lc( qx(sh -c '( id -un ; id -gn) 2>/dev/null' 2>nul ) || 'n/a' ));
if ($@) {
@gids = (
lc(
qx(sh -c '( id -un ; id -gn) 2>/dev/null' 2>nul ) || 'n/a'
)
);
}
$data->{groups} = [ @gids ];
$data->{groups} = [@gids];

$data->{uid} = getlogin() || getpwuid($>);
$data->{umask} = umask;

return _json( $req, $res, 200, $data );
}

$res->header( -type => 'image/png', -status => '200', @headers );
$res->print(decode_base64( '
$res->header( -type => 'image/png', -status => '200', @headers );
$res->print(
decode_base64( '
iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
bWFnZVJlYWR5ccllPAAAA2tpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp
bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6
Expand All @@ -137,10 +151,12 @@ vZoGk3sOiQCowlNfTsEVLXyz8D/jGcb/Dc8aUDSD+EiG/4QZAHZB+N3w/9//focrvvr96v+f/37C
+bVPa1FchuyCLTDBwDuB/3/8+/EfHWDR/B+qDxyIK+Gp5MN6htj7sQy///8G8/8BYc6jHIbm583Y
ImYxLCUyg90BSbZg4MbnxrBAYQED0M8Ms97MwpUig5CTMiglHiYmMQHBCyA2hNLwpHwHiPWgJjMQ
yAt6MM3omQkGQoA4AYjNoBkMlHFOAfECIF6DrhggwACh3ufkau2NHAAAAABJRU5ErkJggg==
' ));
' )
);
return $res;
}
1;

#>>>
__END__
Expand Down
14 changes: 10 additions & 4 deletions core/lib/Foswiki/UI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,6 @@ sub handleRequest {
my $req = shift;

my $res;
if ( $req->queryParam('configurationTest') ) {
require Foswiki::Configure::ImageTest;
return Foswiki::Configure::ImageTest::respond($req);
}

my $dispatcher = $Foswiki::cfg{SwitchBoard}{ $req->action() };
unless ( defined $dispatcher ) {
Expand Down Expand Up @@ -353,6 +349,16 @@ sub _execute {
);

$res = $session->{response};

# SMELL: HACK HACK. Ugly hack to allow configure to test the mainline
# execution path. Now that configure is based on the Foswiki Engine, we
# probably don't need this any more. ImageTest checks security same as
# configure.
if ( $req->queryParam('configurationTest') ) {
require Foswiki::Configure::ImageTest;
return Foswiki::Configure::ImageTest::respond( $req, $res );
}

unless ( defined $res->status() && $res->status() =~ /^\s*3\d\d/ ) {
$session->getLoginManager()->checkAccess();
&$sub($session);
Expand Down

0 comments on commit 256fa4e

Please sign in to comment.