mirror of
https://github.com/curl/curl.git
synced 2026-05-30 06:17:28 +03:00
urlapi: make dedotdotify handle leading dots correctly
Paths starting with one or two leading dots but without a following
slash were not handled correctly.
Follow-up to c31dd6631f
Extended test 1395 accordingly with a set of new test string.
Reported by Codex Security
Closes #20974
This commit is contained in:
parent
acb4fcb2ef
commit
3f06e27502
2 changed files with 44 additions and 5 deletions
14
lib/urlapi.c
14
lib/urlapi.c
|
|
@ -718,8 +718,12 @@ UNITTEST int dedotdotify(const char *input, size_t clen, char **outp)
|
|||
struct dynbuf out;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* variables for leading dot checks */
|
||||
const char *dinput = input;
|
||||
size_t dlen = clen;
|
||||
|
||||
*outp = NULL;
|
||||
/* the path always starts with a slash, and a slash has not dot */
|
||||
/* a single byte path cannot be cleaned up */
|
||||
if(clen < 2)
|
||||
return 0;
|
||||
|
||||
|
|
@ -727,9 +731,9 @@ UNITTEST int dedotdotify(const char *input, size_t clen, char **outp)
|
|||
|
||||
/* A. If the input buffer begins with a prefix of "../" or "./", then
|
||||
remove that prefix from the input buffer; otherwise, */
|
||||
if(is_dot(&input, &clen)) {
|
||||
const char *p = input;
|
||||
size_t blen = clen;
|
||||
if(is_dot(&dinput, &dlen)) {
|
||||
const char *p = dinput;
|
||||
size_t blen = dlen;
|
||||
|
||||
if(!clen)
|
||||
/* . [end] */
|
||||
|
|
@ -737,7 +741,7 @@ UNITTEST int dedotdotify(const char *input, size_t clen, char **outp)
|
|||
else if(ISSLASH(*p)) {
|
||||
/* one dot followed by a slash */
|
||||
input = p + 1;
|
||||
clen--;
|
||||
clen = dlen - 1;
|
||||
}
|
||||
|
||||
/* D. if the input buffer consists only of "." or "..", then remove
|
||||
|
|
|
|||
|
|
@ -37,6 +37,21 @@ static CURLcode test_unit1395(const char *arg)
|
|||
};
|
||||
|
||||
const struct dotdot pairs[] = {
|
||||
{ "/%2f%2e%2e%2f/../a", "/a" },
|
||||
{ "/%2f%2e%2e%2f/../", "/" },
|
||||
{ "/%2f%2e%2e%2f/.", "/%2f%2e%2e%2f/" },
|
||||
{ "/%2f%2e%2e%2f/", "/%2f%2e%2e%2f/" },
|
||||
{ "/%2f%2e%2e%2f", "/%2f%2e%2e%2f" },
|
||||
{ "/%2f%2e%2e%2", "/%2f%2e%2e%2" },
|
||||
{ "/%2f%2e%2e%", "/%2f%2e%2e%" },
|
||||
{ "/%2f%2e%2e", "/%2f%2e%2e" },
|
||||
{ "/%2f%2e%2", "/%2f%2e%2" },
|
||||
{ "/%2f%2e%", "/%2f%2e%" },
|
||||
{ "/%2f%2e", "/%2f%2e" },
|
||||
{ "/%2f%2", "/%2f%2" },
|
||||
{ "/%2f%", "/%2f%" },
|
||||
{ "/%2f", "/%2f" },
|
||||
{ "/%2", "/%2" },
|
||||
{ "%2f%2e%2e%2f/../a", "%2f%2e%2e%2f/a" },
|
||||
{ "%2f%2e%2e%2f/../", "%2f%2e%2e%2f/" },
|
||||
{ "%2f%2e%2e%2f/.", "%2f%2e%2e%2f/" },
|
||||
|
|
@ -108,6 +123,26 @@ static CURLcode test_unit1395(const char *arg)
|
|||
{ "/moo/..", "/" },
|
||||
{ "/..", "/" },
|
||||
{ "/.", "/" },
|
||||
{ "////../a", "///a" },
|
||||
{ "/../../../../../../", "/" },
|
||||
{ "/..//..//", "//" },
|
||||
{ "/.config/../ssh", "/ssh" },
|
||||
{ "/..config/..", "/" },
|
||||
{ "/.../a", "/.../a" },
|
||||
{ "/a/%2E%2e/b", "/b" },
|
||||
{ "/a/%2e./b", "/b" },
|
||||
{ "/a/.%2e/b", "/b" },
|
||||
{ "/%2f..%2f", "/%2f..%2f" },
|
||||
{ "/a/b/.", "/a/b/" },
|
||||
{ "/a/b/..", "/a/" },
|
||||
{ "well-known", "well-known" },
|
||||
{ ".well-known", ".well-known" },
|
||||
{ "..well-known", "..well-known" },
|
||||
{ "...well-known", "...well-known" },
|
||||
{ "....well-known", "....well-known" },
|
||||
{ "%2ewell-known", "%2ewell-known" },
|
||||
{ "%2Ewell-known", "%2Ewell-known" },
|
||||
{ "../.well-known", ".well-known" },
|
||||
};
|
||||
|
||||
for(i = 0; i < CURL_ARRAYSIZE(pairs); i++) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue