summaryrefslogtreecommitdiff
path: root/src/tipideed/responses.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-10-19 18:12:40 +0000
committerLaurent Bercot <ska@appnovation.com>2023-10-19 18:12:40 +0000
commitbaedc8a662d5dc89e76cab254be941c768e71c9c (patch)
treef81a91d745033b3cc037cc221903ac51f275b5f1 /src/tipideed/responses.c
parente782d9cf91c4b5b92897032277c795126d404889 (diff)
downloadtipidee-baedc8a662d5dc89e76cab254be941c768e71c9c.tar.xz
Stop directory traversal attacks in custom response files
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/tipideed/responses.c')
-rw-r--r--src/tipideed/responses.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/src/tipideed/responses.c b/src/tipideed/responses.c
index 70dcddf..3f42d85 100644
--- a/src/tipideed/responses.c
+++ b/src/tipideed/responses.c
@@ -2,6 +2,7 @@
#include <skalibs/bsdsnowflake.h>
+#include <string.h>
#include <unistd.h>
#include <skalibs/stat.h>
@@ -56,13 +57,12 @@ void response_error (tipidee_rql const *rql, char const *docroot, unsigned int s
if (file)
{
int fd ;
- if (file[0] == '/')
- {
- char fmt[UINT_FMT] ;
- fmt[uint_fmt(fmt, status)] = 0 ;
- strerr_dief4x(102, "bad configuration: absolute path for custom ", fmt, " file: ", file) ;
- }
- fd = open_read(file) ;
+ if (sarealpath(&g.sa, file) == -1 || !stralloc_0(&g.sa))
+ die500sys(rql, 111, docroot, "realpath ", file) ;
+ if (strncmp(g.sa.s + salen, g.sa.s, g.cwdlen) || g.sa.s[salen + g.cwdlen] != '/')
+ die500x(rql, 102, docroot, "custom response file ", file, " points outside of the server's root") ;
+ fd = open_read(g.sa.s + salen + g.cwdlen + 1) ;
+ g.sa.len = salen ;
if (fd == -1) strerr_warnwu3sys("open ", "custom response file ", file) ;
else
{
@@ -79,9 +79,9 @@ void response_error (tipidee_rql const *rql, char const *docroot, unsigned int s
}
else
{
- tipidee_response_file_g(buffer_1, rql, status, dt.reason, &st, tipidee_conf_get_content_type(&g.conf, file), options) ;
+ tipidee_response_file_g(buffer_1, rql, status, dt.reason, &st, tipidee_conf_get_content_type(&g.conf, g.sa.s + salen + g.cwdlen + 1), options) ;
tipidee_log_answer(g.logv, rql, status, st.st_size) ;
- send_file(fd, st.st_size, file) ;
+ send_file(fd, st.st_size, g.sa.s + salen + g.cwdlen + 1) ;
fd_close(fd) ;
return ;
}