diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-09 04:41:55 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-09 05:54:53 +0200 |
| commit | b5282b23653b3a46ab6ae2d84049abadcc8a8a1d (patch) | |
| tree | 182e9fd51ca2d9678089efd41439848d61aada23 | |
| parent | fbd730754b83dd9ae95d9b308e29ba7e85001528 (diff) | |
| download | slcl-b5282b23653b3a46ab6ae2d84049abadcc8a8a1d.tar.gz | |
main.c: Disallow invalid filenames or directory names
- Relative paths must not be used for filenames or directory names,
such as "..", "." or "dir/..".
- Paths with asterisks ('*') must not be allowed, to avoid confusion
with wildcard expressions.
| -rw-r--r-- | main.c | 65 |
1 files changed, 52 insertions, 13 deletions
@@ -370,6 +370,21 @@ static bool path_isrel(const char *const path) return false; } +static bool path_invalid(const char *const path) +{ + return path_isrel(path) || strchr(path, '*'); +} + +static bool filename_invalid(const char *const path) +{ + return path_invalid(path) || strchr(path, '/'); +} + +static bool dirname_invalid(const char *const path) +{ + return *path != '/' || path[strlen(path) - 1] != '/' || path_invalid(path); +} + static int getpublic(const struct http_payload *const p, struct http_response *const r, void *const user) { @@ -385,7 +400,7 @@ static int getpublic(const struct http_payload *const p, fprintf(stderr, "%s: auth_dir failed\n", __func__); goto end; } - else if (path_isrel(p->resource)) + else if (path_invalid(p->resource)) { fprintf(stderr, "%s: illegal relative path %s\n", __func__, p->resource); @@ -520,14 +535,14 @@ static int check_search_input(const struct http_payload *const p, *f = page_bad_request; goto end; } - else if (path_isrel(tdir) || *tdir != '/' || tdir[strlen(tdir) - 1] != '/') + else if (dirname_invalid(tdir)) { fprintf(stderr, "%s: invalid directory %s\n", __func__, tdir); ret = 1; *f = page_bad_request; goto end; } - else if (strchr(tres, '/') || path_isrel(tres)) + else if (filename_invalid(tres)) { fprintf(stderr, "%s: invalid resource %s\n", __func__, tres); ret = 1; @@ -741,7 +756,7 @@ static int share(const struct http_payload *const p, const char *const path = forms->value, *const username = p->cookie.field; - if (path_isrel(path)) + if (path_invalid(path)) { fprintf(stderr, "%s: invalid path %s\n", __func__, path); ret = page_bad_request(r); @@ -870,7 +885,7 @@ static int getnode(const struct http_payload *const p, const char *const username = p->cookie.field, *const resource = p->resource + strlen("/user/"); - if (path_isrel(resource)) + if (path_invalid(resource)) { fprintf(stderr, "%s: illegal relative path %s\n", __func__, resource); return page_forbidden(r); @@ -1124,6 +1139,11 @@ static int upload_files(const struct http_payload *const p, return 0; } + else if (dirname_invalid(dir)) + { + fprintf(stderr, "%s: invalid directory %s\n", __func__, dir); + return page_bad_request(r); + } for (size_t i = 0; i < po->n; i++) { @@ -1218,13 +1238,13 @@ static int createdir(const struct http_payload *const p, ret = page_bad_request(r); goto end; } - else if (path_isrel(name) || strpbrk(name, "/*")) + else if (filename_invalid(name)) { fprintf(stderr, "%s: invalid directory name %s\n", __func__, dir); ret = page_bad_request(r); goto end; } - else if (path_isrel(dir) || strchr(dir, '*')) + else if (dirname_invalid(dir)) { fprintf(stderr, "%s: invalid name %s\n", __func__, name); ret = page_bad_request(r); @@ -1318,6 +1338,15 @@ static int check_rm_input(const struct form *const forms, const size_t n, } else if (!strcmp(f->key, "path")) { + const char *const path = f->value; + + if (path_isrel(path)) + { + fprintf(stderr, "%s: invalid path %s\n", __func__, rm->dir); + *cb = page_bad_request; + return 1; + } + const char **tmp = realloc(rm->items, (rm->n + 1) * sizeof *tmp); if (!tmp) @@ -1327,7 +1356,7 @@ static int check_rm_input(const struct form *const forms, const size_t n, return -1; } - tmp[rm->n++] = f->value; + tmp[rm->n++] = path; rm->items = tmp; } } @@ -1338,7 +1367,7 @@ static int check_rm_input(const struct form *const forms, const size_t n, *cb = page_bad_request; return 1; } - else if (*rm->dir != '/' || path_isrel(rm->dir)) + else if (dirname_invalid(rm->dir)) { fprintf(stderr, "%s: invalid directory %s\n", __func__, rm->dir); *cb = page_bad_request; @@ -1526,10 +1555,20 @@ static int do_rm(const struct form *const forms, const size_t n, { const struct form *const f = &forms[i]; - if (!strcmp(f->key, "path") && rm_item(dir, f->value)) + if (!strcmp(f->key, "path")) { - fprintf(stderr, "%s: rm_item failed\n", __func__); - return -1; + const char *const path = f->value; + + if (path_isrel(path)) + { + fprintf(stderr, "%s: invalid path %s\n", __func__, path); + return 1; + } + else if (rm_item(dir, f->value)) + { + fprintf(stderr, "%s: rm_item failed\n", __func__); + return -1; + } } } @@ -1580,7 +1619,7 @@ static int rm(const struct http_payload *const p, ret = f(r); goto end; } - else if (*dir != '/' || path_isrel(dir)) + else if (dirname_invalid(dir)) { fprintf(stderr, "%s: invalid directory %s\n", __func__, dir); ret = page_bad_request(r); |
