]> git.seodisparate.com - c_simple_http/commitdiff
Fix potential invalid path when fetching static
authorStephen Seo <seo.disparate@gmail.com>
Sun, 3 Nov 2024 08:54:55 +0000 (17:54 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sun, 3 Nov 2024 08:54:55 +0000 (17:54 +0900)
src/main.c
src/static.c
src/static.h

index 3beaefe8d66e9d58915ea7c5bc66244ccb2fc4ec..edeb6f01f2cb89beff1ba275ca6defcbf437d01a 100644 (file)
@@ -452,6 +452,8 @@ int main(int argc, char **argv) {
             response_code = C_SIMPLE_HTTP_Response_400_Bad_Request;
           } else if (file_info.result == STATIC_FILE_RESULT_404NotFound) {
             response_code = C_SIMPLE_HTTP_Response_404_Not_Found;
+          } else if (file_info.result == STATIC_FILE_RESULT_InvalidPath) {
+            response_code = C_SIMPLE_HTTP_Response_400_Bad_Request;
           } else {
             response_code = C_SIMPLE_HTTP_Response_500_Internal_Server_Error;
           }
index 18c9e9212cdbdfa12c2df511f380dc995a029c86..2414fbaa6b5367ee6a110ad15190e63868c136eb 100644 (file)
@@ -120,6 +120,9 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
   } else if (!ignore_mime_type && !c_simple_http_is_xdg_mime_available()) {
     file_info.result = STATIC_FILE_RESULT_NoXDGMimeAvailable;
     return file_info;
+  } else if (c_simple_http_static_validate_path(path) != 0) {
+    file_info.result = STATIC_FILE_RESULT_InvalidPath;
+    return file_info;
   }
 
   uint64_t buf_size = 128;
@@ -298,4 +301,17 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
   return file_info;
 }
 
+int c_simple_http_static_validate_path(const char *path) {
+  uint64_t length = strlen(path);
+  for (uint64_t idx = 0; idx <= length && path[idx] != 0; ++idx) {
+    if (length - idx >= 2) {
+      if (path[idx] == '.' && path[idx + 1] == '.') {
+        // Contains "..", invalid.
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+
 // vim: et ts=2 sts=2 sw=2
index 98deed8e61bf03c1cf1adf539613bcfde87f49b2..d36b1bc131430d52c041116a066edadfc215dc27 100644 (file)
@@ -26,7 +26,8 @@ typedef enum C_SIMPLE_HTTP_StaticFileResult {
   STATIC_FILE_RESULT_InvalidParameter,
   STATIC_FILE_RESULT_NoXDGMimeAvailable,
   STATIC_FILE_RESULT_InternalError,
-  STATIC_FILE_RESULT_404NotFound
+  STATIC_FILE_RESULT_404NotFound,
+  STATIC_FILE_RESULT_InvalidPath
 } C_SIMPLE_HTTP_StaticFileResult;
 
 typedef struct C_SIMPLE_HTTP_StaticFileInfo {
@@ -47,6 +48,9 @@ void c_simple_http_cleanup_static_file_info(
 C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
   const char *static_dir, const char *path, int_fast8_t ignore_mime_type);
 
+/// Returns zero if OK.
+int c_simple_http_static_validate_path(const char *path);
+
 #endif
 
 // vim: et ts=2 sts=2 sw=2