Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

(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...
  • Loading branch information...
commit f636ce3ba3e340569b26d1e47b9d9b62dd8a3bf2 1 parent 0d371ac
Sitaram Chamarty authored October 05, 2012
2  src/gitolite-shell
@@ -168,7 +168,7 @@ sub sanity {
168 168
     my $repo = shift;
169 169
     _die "'$repo' contains bad characters" if $repo !~ $REPONAME_PATT;
170 170
     _die "'$repo' ends with a '/'"         if $repo =~ m(/$);
171  
-    _die "'$repo' contains '..'"           if $repo =~ m(\.\.$);
  171
+    _die "'$repo' contains '..'"           if $repo =~ m(\.\.);
172 172
 }
173 173
 
174 174
 # ----------------------------------------------------------------------
15  src/lib/Gitolite/Conf/Load.pm
@@ -67,8 +67,9 @@ my $last_repo = '';
67 67
 
68 68
 sub access {
69 69
     my ( $repo, $user, $aa, $ref ) = @_;
70  
-    _die "invalid repo '$repo'" if not( $repo and $repo =~ $REPOPATT_PATT );
71 70
     _die "invalid user '$user'" if not( $user and $user =~ $USERNAME_PATT );
  71
+    sanity($repo);
  72
+
72 73
     my $deny_rules = option( $repo, 'deny-rules' );
73 74
     load($repo);
74 75
 
@@ -175,8 +176,18 @@ sub option {
175 176
     return $ret->{$option};
176 177
 }
177 178
 
  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
+
178 187
 sub repo_missing {
179 188
     my $repo = shift;
  189
+    sanity($repo);
  190
+
180 191
     return not -d "$rc{GL_REPO_BASE}/$repo.git";
181 192
 }
182 193
 
@@ -400,6 +411,8 @@ sub generic_name {
400 411
 
401 412
 sub creator {
402 413
     my $repo = shift;
  414
+    sanity($repo);
  415
+
403 416
     return ( $ENV{GL_USER} || '' ) if repo_missing($repo);
404 417
     my $f       = "$rc{GL_REPO_BASE}/$repo.git/gl-creator";
405 418
     my $creator = '';
19  t/0-me-first.t
@@ -6,10 +6,12 @@ use warnings;
6 6
 use lib "src/lib";
7 7
 use Gitolite::Test;
8 8
 
  9
+my $rb = `gitolite query-rc -n GL_REPO_BASE`;
  10
+
9 11
 # initial smoke tests
10 12
 # ----------------------------------------------------------------------
11 13
 
12  
-try "plan 65";
  14
+try "plan 73";
13 15
 
14 16
 # basic push admin repo
15 17
 confreset;confadd '
@@ -75,4 +77,19 @@ try "
75 77
     glt ls-remote u5 file:///cc/1;  ok;     perl s/TRACE.*//g; !/\\S/
76 78
     glt ls-remote u5 file:///cc/2;  !ok;    /DENIED by fallthru/
77 79
     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
+
78 95
 ";

0 notes on commit f636ce3

Please sign in to comment.
Something went wrong with that request. Please try again.