diff --git a/src/static.c b/src/static.c index 429dd8e..fc682e0 100644 --- a/src/static.c +++ b/src/static.c @@ -304,12 +304,28 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file( int c_simple_http_static_validate_path(const char *path) { uint64_t length = strlen(path); + + if (length >= 3 && path[0] == '.' && path[1] == '.' && path[2] == '/') { + // Starts with "..", invalid. + return 1; + } + for (uint64_t idx = 0; idx <= length && path[idx] != 0; ++idx) { - if (length - idx >= 2) { - if (path[idx] == '.' && path[idx + 1] == '.') { + if (length - idx >= 4) { + if (path[idx] == '/' + && path[idx + 1] == '.' + && path[idx + 2] == '.' + && path[idx + 3] == '/') { // Contains "..", invalid. return 1; } + } else if (length - idx == 3) { + if (path[idx] == '/' + && path[idx + 1] == '.' + && path[idx + 2] == '.') { + // Ends with "..", invalid. + return 1; + } } } return 0; diff --git a/src/test.c b/src/test.c index 2f2b03e..b2382b4 100644 --- a/src/test.c +++ b/src/test.c @@ -1004,6 +1004,11 @@ int main(int argc, char **argv) { CHECK_TRUE(info.result == STATIC_FILE_RESULT_OK); CHECK_STREQ(info.mime_type, "application/octet-stream"); c_simple_http_cleanup_static_file_info(&info); + + CHECK_TRUE(c_simple_http_static_validate_path("../derp") != 0); + CHECK_TRUE(c_simple_http_static_validate_path("./derp") == 0); + CHECK_TRUE(c_simple_http_static_validate_path("./../derp") != 0); + CHECK_TRUE(c_simple_http_static_validate_path("/derp/..") != 0); } RETURN()