about summary refs log tree commit diff
path: root/src
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
parente782d9cf91c4b5b92897032277c795126d404889 (diff)
downloadtipidee-baedc8a662d5dc89e76cab254be941c768e71c9c.tar.gz
tipidee-baedc8a662d5dc89e76cab254be941c768e71c9c.tar.xz
tipidee-baedc8a662d5dc89e76cab254be941c768e71c9c.zip
Stop directory traversal attacks in custom response files
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-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 ;
       }