From 2f0f3d45f4335327c269a689fbeb62b3003695aa Mon Sep 17 00:00:00 2001 From: la_ninpre Date: Wed, 28 Jan 2026 11:30:03 +0300 Subject: static files: allow files in a subdirectory allowing '/' in paths is a bit scary, but replacing the check with reject on '..' seems to work. please correct me if i'm wrong and this is insecure. --- data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'data.c') diff --git a/data.c b/data.c index 27825ad..02686e1 100644 --- a/data.c +++ b/data.c @@ -2691,7 +2691,7 @@ static int _load_raw_file(const char *fn, xs_val **data, int *size, xs_str *_static_fn(snac *snac, const char *id) /* gets the filename for a static file */ { - if (strchr(id, '/')) + if (strstr(id, "..")) return NULL; else return xs_fmt("%s/static/%s", snac->basedir, id); -- cgit From 16d48e4cd4edc15aa2ffe158d93248b5a57c3ea9 Mon Sep 17 00:00:00 2001 From: la_ninpre Date: Wed, 28 Jan 2026 12:23:56 +0300 Subject: data: don't try to read something that's not a regular file --- data.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'data.c') diff --git a/data.c b/data.c index 02686e1..85bc401 100644 --- a/data.c +++ b/data.c @@ -2665,14 +2665,17 @@ static int _load_raw_file(const char *fn, xs_val **data, int *size, } else { /* newer or never downloaded; read the full file */ + struct stat sb; FILE *f; - if ((f = fopen(fn, "rb")) != NULL) { - *size = XS_ALL; - *data = xs_read(f, size); - fclose(f); + if (stat(fn, &sb) == 0 && sb.st_mode & S_IFMT == S_IFREG) { + if ((f = fopen(fn, "rb")) != NULL) { + *size = XS_ALL; + *data = xs_read(f, size); + fclose(f); - status = HTTP_STATUS_OK; + status = HTTP_STATUS_OK; + } } } -- cgit From 1c2e3032e76e55883b4ea0add35ba805e16aa7ea Mon Sep 17 00:00:00 2001 From: la_ninpre Date: Wed, 28 Jan 2026 13:03:02 +0300 Subject: data: fix checking for a file type --- data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'data.c') diff --git a/data.c b/data.c index 85bc401..31eafeb 100644 --- a/data.c +++ b/data.c @@ -2668,7 +2668,7 @@ static int _load_raw_file(const char *fn, xs_val **data, int *size, struct stat sb; FILE *f; - if (stat(fn, &sb) == 0 && sb.st_mode & S_IFMT == S_IFREG) { + if (stat(fn, &sb) == 0 && (sb.st_mode&S_IFMT) == S_IFREG) { if ((f = fopen(fn, "rb")) != NULL) { *size = XS_ALL; *data = xs_read(f, size); -- cgit From 63903b9c46ad30e5007b689dc68867ae3aa13a5b Mon Sep 17 00:00:00 2001 From: lbr Date: Sun, 8 Feb 2026 08:46:46 +0100 Subject: data: use lstat() instead of stat() this disallows snac to serve a static file which is a symlink. --- data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'data.c') diff --git a/data.c b/data.c index 31eafeb..762d0fd 100644 --- a/data.c +++ b/data.c @@ -2668,7 +2668,7 @@ static int _load_raw_file(const char *fn, xs_val **data, int *size, struct stat sb; FILE *f; - if (stat(fn, &sb) == 0 && (sb.st_mode&S_IFMT) == S_IFREG) { + if (lstat(fn, &sb) == 0 && (sb.st_mode&S_IFMT) == S_IFREG) { if ((f = fopen(fn, "rb")) != NULL) { *size = XS_ALL; *data = xs_read(f, size); -- cgit