Skip to content

Commit f636ce3

Browse files
committed
(security) fix bug in pattern to detect path traversal
while we're about it, add the same check to some of the internal routines, so that commands can also be protected. finally, just to make sure we don't lose it again in some other fashion, add a few tests for path traversal...
1 parent 0d371ac commit f636ce3

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

Diff for: src/gitolite-shell

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ sub sanity {
168168
my $repo = shift;
169169
_die "'$repo' contains bad characters" if $repo !~ $REPONAME_PATT;
170170
_die "'$repo' ends with a '/'" if $repo =~ m(/$);
171-
_die "'$repo' contains '..'" if $repo =~ m(\.\.$);
171+
_die "'$repo' contains '..'" if $repo =~ m(\.\.);
172172
}
173173
174174
# ----------------------------------------------------------------------

Diff for: src/lib/Gitolite/Conf/Load.pm

+14-1
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ my $last_repo = '';
6767

6868
sub access {
6969
my ( $repo, $user, $aa, $ref ) = @_;
70-
_die "invalid repo '$repo'" if not( $repo and $repo =~ $REPOPATT_PATT );
7170
_die "invalid user '$user'" if not( $user and $user =~ $USERNAME_PATT );
71+
sanity($repo);
72+
7273
my $deny_rules = option( $repo, 'deny-rules' );
7374
load($repo);
7475

@@ -175,8 +176,18 @@ sub option {
175176
return $ret->{$option};
176177
}
177178

179+
sub sanity {
180+
my $repo = shift;
181+
182+
_die "invalid repo '$repo'" if not( $repo and $repo =~ $REPOPATT_PATT );
183+
_die "'$repo' ends with a '/'" if $repo =~ m(/$);
184+
_die "'$repo' contains '..'" if $repo =~ $REPONAME_PATT and $repo =~ m(\.\.);
185+
}
186+
178187
sub repo_missing {
179188
my $repo = shift;
189+
sanity($repo);
190+
180191
return not -d "$rc{GL_REPO_BASE}/$repo.git";
181192
}
182193
@@ -400,6 +411,8 @@ sub generic_name {
400411
401412
sub creator {
402413
my $repo = shift;
414+
sanity($repo);
415+
403416
return ( $ENV{GL_USER} || '' ) if repo_missing($repo);
404417
my $f = "$rc{GL_REPO_BASE}/$repo.git/gl-creator";
405418
my $creator = '';

Diff for: t/0-me-first.t

+18-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ use warnings;
66
use lib "src/lib";
77
use Gitolite::Test;
88

9+
my $rb = `gitolite query-rc -n GL_REPO_BASE`;
10+
911
# initial smoke tests
1012
# ----------------------------------------------------------------------
1113

12-
try "plan 65";
14+
try "plan 73";
1315

1416
# basic push admin repo
1517
confreset;confadd '
@@ -75,4 +77,19 @@ try "
7577
glt ls-remote u5 file:///cc/1; ok; perl s/TRACE.*//g; !/\\S/
7678
glt ls-remote u5 file:///cc/2; !ok; /DENIED by fallthru/
7779
glt ls-remote u6 file:///cc/2; !ok; /DENIED by fallthru/
80+
81+
# command
82+
glt perms u4 -c cc/bar/baz/frob + READERS u2;
83+
ok; /Initialized empty .*cc/bar/baz/frob.git/
84+
85+
# path traversal
86+
glt ls-remote u4 file:///cc/dd/../ee
87+
!ok; /FATAL: 'cc/dd/\\.\\./ee' contains '\\.\\.'/
88+
glt ls-remote u5 file:///cc/../../../../../..$rb/gitolite-admin
89+
!ok; /FATAL: 'cc/../../../../../..$rb/gitolite-admin' contains '\\.\\.'/
90+
91+
glt perms u4 -c cc/bar/baz/../frob + READERS u2
92+
!ok; /FATAL: 'cc/bar/baz/\\.\\./frob' contains '\\.\\.'/
93+
94+
7895
";

0 commit comments

Comments
 (0)