diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-03-28 18:53:07 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-03-28 18:56:08 +0200 |
commit | 3253d7fe0097ff15797ee4918e927b0c9d6863a9 (patch) | |
tree | 8e40be294ccd1f11b46080dd9b20223d5429c14a /networking/httpd.c | |
parent | d8a33603801476dd870ea66c36cf7c64d852d674 (diff) | |
download | busybox-w32-3253d7fe0097ff15797ee4918e927b0c9d6863a9.tar.gz busybox-w32-3253d7fe0097ff15797ee4918e927b0c9d6863a9.tar.bz2 busybox-w32-3253d7fe0097ff15797ee4918e927b0c9d6863a9.zip |
httpd: do not mangle cgi-bin/SCRIPT/params URLs
If cgi-bin/ prefix is seen, do not test the rest for existence,
whether it's a dir, and such.
function old new delta
handle_incoming_and_exit 2200 2212 +12
Reported here:
https://lists.zx2c4.com/pipermail/cgit/2023-March/004825.html
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r-- | networking/httpd.c | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index ffc58e10b..252ad6c2d 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -2405,50 +2405,52 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2405 | send_headers_and_exit(HTTP_FORBIDDEN); | 2405 | send_headers_and_exit(HTTP_FORBIDDEN); |
2406 | } | 2406 | } |
2407 | cgi_type = CGI_NORMAL; | 2407 | cgi_type = CGI_NORMAL; |
2408 | } | 2408 | } /* why "else": do not check "cgi-bin/SCRIPT/something" for cases below: */ |
2409 | else | ||
2409 | #endif | 2410 | #endif |
2410 | 2411 | { | |
2411 | if (urlp[-1] == '/') { | 2412 | if (urlp[-1] == '/') { |
2412 | /* When index_page string is appended to <dir>/ URL, it overwrites | 2413 | /* When index_page string is appended to <dir>/ URL, it overwrites |
2413 | * the query string. If we fall back to call /cgi-bin/index.cgi, | 2414 | * the query string. If we fall back to call /cgi-bin/index.cgi, |
2414 | * query string would be lost and not available to the CGI. | 2415 | * query string would be lost and not available to the CGI. |
2415 | * Work around it by making a deep copy. | 2416 | * Work around it by making a deep copy. |
2416 | */ | 2417 | */ |
2417 | if (ENABLE_FEATURE_HTTPD_CGI) | 2418 | if (ENABLE_FEATURE_HTTPD_CGI) |
2418 | g_query = xstrdup(g_query); /* ok for NULL too */ | 2419 | g_query = xstrdup(g_query); /* ok for NULL too */ |
2419 | strcpy(urlp, index_page); | 2420 | strcpy(urlp, index_page); |
2420 | } | 2421 | } |
2421 | if (stat(tptr, &sb) == 0) { | 2422 | if (stat(tptr, &sb) == 0) { |
2422 | /* If URL is a directory with no slash, set up | 2423 | /* If URL is a directory with no slash, set up |
2423 | * "HTTP/1.1 302 Found" "Location: /dir/" reply */ | 2424 | * "HTTP/1.1 302 Found" "Location: /dir/" reply */ |
2424 | if (urlp[-1] != '/' && S_ISDIR(sb.st_mode)) { | 2425 | if (urlp[-1] != '/' && S_ISDIR(sb.st_mode)) { |
2425 | found_moved_temporarily = urlcopy; | 2426 | found_moved_temporarily = urlcopy; |
2426 | } else { | 2427 | } else { |
2427 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 2428 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
2428 | char *suffix = strrchr(tptr, '.'); | 2429 | char *suffix = strrchr(tptr, '.'); |
2429 | if (suffix) { | 2430 | if (suffix) { |
2430 | Htaccess *cur; | 2431 | Htaccess *cur; |
2431 | for (cur = script_i; cur; cur = cur->next) { | 2432 | for (cur = script_i; cur; cur = cur->next) { |
2432 | if (strcmp(cur->before_colon + 1, suffix) == 0) { | 2433 | if (strcmp(cur->before_colon + 1, suffix) == 0) { |
2433 | cgi_type = CGI_INTERPRETER; | 2434 | cgi_type = CGI_INTERPRETER; |
2434 | break; | 2435 | break; |
2436 | } | ||
2435 | } | 2437 | } |
2436 | } | 2438 | } |
2437 | } | ||
2438 | #endif | 2439 | #endif |
2439 | file_size = sb.st_size; | 2440 | file_size = sb.st_size; |
2440 | last_mod = sb.st_mtime; | 2441 | last_mod = sb.st_mtime; |
2442 | } | ||
2441 | } | 2443 | } |
2442 | } | ||
2443 | #if ENABLE_FEATURE_HTTPD_CGI | 2444 | #if ENABLE_FEATURE_HTTPD_CGI |
2444 | else if (urlp[-1] == '/') { | 2445 | else if (urlp[-1] == '/') { |
2445 | /* It's a dir URL and there is no index.html */ | 2446 | /* It's a dir URL and there is no index.html */ |
2446 | /* Is there cgi-bin/index.cgi? */ | 2447 | /* Is there cgi-bin/index.cgi? */ |
2447 | if (access("/cgi-bin/index.cgi"+1, X_OK) != 0) | 2448 | if (access("/cgi-bin/index.cgi"+1, X_OK) != 0) |
2448 | send_headers_and_exit(HTTP_NOT_FOUND); /* no */ | 2449 | send_headers_and_exit(HTTP_NOT_FOUND); /* no */ |
2449 | cgi_type = CGI_INDEX; | 2450 | cgi_type = CGI_INDEX; |
2450 | } | 2451 | } |
2451 | #endif | 2452 | #endif |
2453 | } | ||
2452 | 2454 | ||
2453 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH || ENABLE_FEATURE_HTTPD_CGI | 2455 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH || ENABLE_FEATURE_HTTPD_CGI |
2454 | /* check_user_passwd() would be confused by added .../index.html, truncate it */ | 2456 | /* check_user_passwd() would be confused by added .../index.html, truncate it */ |