From eed710020bc0689768251be7a17787ff12a9763c Mon Sep 17 00:00:00 2001 From: Paul Kulchenko Date: Sun, 20 Mar 2022 11:37:40 -0700 Subject: [PATCH] Improve StoreFile by adding checks and skipping ./ in the stored path Ref #366. --- tool/net/redbean.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tool/net/redbean.c b/tool/net/redbean.c index d88881f18..e8e001dc2 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -3515,11 +3515,17 @@ static void StoreAsset(char *path, size_t pathlen, char *data, size_t datalen, static void StoreFile(char *path) { char *p; - size_t n; + size_t plen, tlen; struct stat st; - if (lstat(path, &st) == -1) DIEF("Can't stat %`'s: %m", path); - if (!(p = xslurp(path, &n))) DIEF("Can't read %`'s: %m", path); - StoreAsset(path, strlen(path), p, n, st.st_mode & 0777); + char *target = path; + if (startswith(target, "./")) target += 2; + tlen = strlen(target); + if (!IsReasonablePath(target, tlen)) + DIEF("(cfg) error: can't store %`'s: contains '.' or '..' segments", target); + if (lstat(path, &st) == -1) DIEF("(cfg) error: can't stat %`'s: %m", path); + if (!(p = xslurp(path, &plen))) DIEF("(cfg) error: can't read %`'s: %m", path); + StoreAsset(target, tlen, p, plen, st.st_mode & 0777); + free(p); } static void StorePath(const char *dirpath) { @@ -3528,7 +3534,7 @@ static void StorePath(const char *dirpath) { struct dirent *e; if (!isdirectory(dirpath) && !endswith(dirpath, "/")) return StoreFile(dirpath); - if (!(d = opendir(dirpath))) DIEF("Can't open %`'s", dirpath); + if (!(d = opendir(dirpath))) DIEF("(cfg) error: can't open %`'s", dirpath); while ((e = readdir(d))) { if (strcmp(e->d_name, ".") == 0) continue; if (strcmp(e->d_name, "..") == 0) continue;