-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
http-backend: Protect GIT_PROJECT_ROOT from /../ requests
Eons ago HPA taught git-daemon how to protect itself from /../ attacks, which Junio brought back into service in d79374c ("daemon.c and path.enter_repo(): revamp path validation"). I did not carry this into git-http-backend as originally we relied only upon PATH_TRANSLATED, and assumed the HTTP server had done its access control checks to validate the resolved path was within a directory permitting access from the remote client. This would usually be sufficient to protect a server from requests for its /etc/passwd file by http://host/smart/../etc/passwd sorts of URLs. However in 917adc0 Mark Lodato added GIT_PROJECT_ROOT as an additional method of configuring the CGI. When this environment variable is used the web server does not generate the final access path and therefore may blindly pass through "/../etc/passwd" in PATH_INFO under the assumption that "/../" might have special meaning to the invoked CGI. Instead of permitting these sorts of malformed path requests, we now reject them back at the client, with an error message for the server log. This matches git-daemon behavior. Signed-off-by: Shawn O. Pearce <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
- Loading branch information
Showing
5 changed files
with
86 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,53 +101,6 @@ static void NORETURN daemon_die(const char *err, va_list params) | |
exit(1); | ||
} | ||
|
||
static int avoid_alias(char *p) | ||
{ | ||
int sl, ndot; | ||
|
||
/* | ||
* This resurrects the belts and suspenders paranoia check by HPA | ||
* done in <[email protected]> thread, now enter_repo() | ||
* does not do getcwd() based path canonicalizations. | ||
* | ||
* sl becomes true immediately after seeing '/' and continues to | ||
* be true as long as dots continue after that without intervening | ||
* non-dot character. | ||
*/ | ||
if (!p || (*p != '/' && *p != '~')) | ||
return -1; | ||
sl = 1; ndot = 0; | ||
p++; | ||
|
||
while (1) { | ||
char ch = *p++; | ||
if (sl) { | ||
if (ch == '.') | ||
ndot++; | ||
else if (ch == '/') { | ||
if (ndot < 3) | ||
/* reject //, /./ and /../ */ | ||
return -1; | ||
ndot = 0; | ||
} | ||
else if (ch == 0) { | ||
if (0 < ndot && ndot < 3) | ||
/* reject /.$ and /..$ */ | ||
return -1; | ||
return 0; | ||
} | ||
else | ||
sl = ndot = 0; | ||
} | ||
else if (ch == 0) | ||
return 0; | ||
else if (ch == '/') { | ||
sl = 1; | ||
ndot = 0; | ||
} | ||
} | ||
} | ||
|
||
static char *path_ok(char *directory) | ||
{ | ||
static char rpath[PATH_MAX]; | ||
|
@@ -157,7 +110,7 @@ static char *path_ok(char *directory) | |
|
||
dir = directory; | ||
|
||
if (avoid_alias(dir)) { | ||
if (daemon_avoid_alias(dir)) { | ||
logerror("'%s': aliased", dir); | ||
return NULL; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -564,3 +564,50 @@ char *strip_path_suffix(const char *path, const char *suffix) | |
return NULL; | ||
return xstrndup(path, chomp_trailing_dir_sep(path, path_len)); | ||
} | ||
|
||
int daemon_avoid_alias(const char *p) | ||
{ | ||
int sl, ndot; | ||
|
||
/* | ||
* This resurrects the belts and suspenders paranoia check by HPA | ||
* done in <[email protected]> thread, now enter_repo() | ||
* does not do getcwd() based path canonicalizations. | ||
* | ||
* sl becomes true immediately after seeing '/' and continues to | ||
* be true as long as dots continue after that without intervening | ||
* non-dot character. | ||
*/ | ||
if (!p || (*p != '/' && *p != '~')) | ||
return -1; | ||
sl = 1; ndot = 0; | ||
p++; | ||
|
||
while (1) { | ||
char ch = *p++; | ||
if (sl) { | ||
if (ch == '.') | ||
ndot++; | ||
else if (ch == '/') { | ||
if (ndot < 3) | ||
/* reject //, /./ and /../ */ | ||
return -1; | ||
ndot = 0; | ||
} | ||
else if (ch == 0) { | ||
if (0 < ndot && ndot < 3) | ||
/* reject /.$ and /..$ */ | ||
return -1; | ||
return 0; | ||
} | ||
else | ||
sl = ndot = 0; | ||
} | ||
else if (ch == 0) | ||
return 0; | ||
else if (ch == '/') { | ||
sl = 1; | ||
ndot = 0; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters