diff options
author | Denys Vlasenko | 2023-03-28 18:53:07 +0200 |
---|---|---|
committer | Denys Vlasenko | 2023-03-28 18:56:08 +0200 |
commit | 3253d7fe0097ff15797ee4918e927b0c9d6863a9 (patch) | |
tree | 8e40be294ccd1f11b46080dd9b20223d5429c14a /networking/httpd.c | |
parent | d8a33603801476dd870ea66c36cf7c64d852d674 (diff) | |
download | busybox-3253d7fe0097ff15797ee4918e927b0c9d6863a9.zip busybox-3253d7fe0097ff15797ee4918e927b0c9d6863a9.tar.gz |
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 'networking/httpd.c')
-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 ffc58e1..252ad6c 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -2405,50 +2405,52 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) send_headers_and_exit(HTTP_FORBIDDEN); } cgi_type = CGI_NORMAL; - } + } /* why "else": do not check "cgi-bin/SCRIPT/something" for cases below: */ + else #endif - - if (urlp[-1] == '/') { - /* When index_page string is appended to <dir>/ URL, it overwrites - * the query string. If we fall back to call /cgi-bin/index.cgi, - * query string would be lost and not available to the CGI. - * Work around it by making a deep copy. - */ - if (ENABLE_FEATURE_HTTPD_CGI) - g_query = xstrdup(g_query); /* ok for NULL too */ - strcpy(urlp, index_page); - } - if (stat(tptr, &sb) == 0) { - /* If URL is a directory with no slash, set up - * "HTTP/1.1 302 Found" "Location: /dir/" reply */ - if (urlp[-1] != '/' && S_ISDIR(sb.st_mode)) { - found_moved_temporarily = urlcopy; - } else { + { + if (urlp[-1] == '/') { + /* When index_page string is appended to <dir>/ URL, it overwrites + * the query string. If we fall back to call /cgi-bin/index.cgi, + * query string would be lost and not available to the CGI. + * Work around it by making a deep copy. + */ + if (ENABLE_FEATURE_HTTPD_CGI) + g_query = xstrdup(g_query); /* ok for NULL too */ + strcpy(urlp, index_page); + } + if (stat(tptr, &sb) == 0) { + /* If URL is a directory with no slash, set up + * "HTTP/1.1 302 Found" "Location: /dir/" reply */ + if (urlp[-1] != '/' && S_ISDIR(sb.st_mode)) { + found_moved_temporarily = urlcopy; + } else { #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR - char *suffix = strrchr(tptr, '.'); - if (suffix) { - Htaccess *cur; - for (cur = script_i; cur; cur = cur->next) { - if (strcmp(cur->before_colon + 1, suffix) == 0) { - cgi_type = CGI_INTERPRETER; - break; + char *suffix = strrchr(tptr, '.'); + if (suffix) { + Htaccess *cur; + for (cur = script_i; cur; cur = cur->next) { + if (strcmp(cur->before_colon + 1, suffix) == 0) { + cgi_type = CGI_INTERPRETER; + break; + } } } - } #endif - file_size = sb.st_size; - last_mod = sb.st_mtime; + file_size = sb.st_size; + last_mod = sb.st_mtime; + } } - } #if ENABLE_FEATURE_HTTPD_CGI - else if (urlp[-1] == '/') { - /* It's a dir URL and there is no index.html */ - /* Is there cgi-bin/index.cgi? */ - if (access("/cgi-bin/index.cgi"+1, X_OK) != 0) - send_headers_and_exit(HTTP_NOT_FOUND); /* no */ - cgi_type = CGI_INDEX; - } + else if (urlp[-1] == '/') { + /* It's a dir URL and there is no index.html */ + /* Is there cgi-bin/index.cgi? */ + if (access("/cgi-bin/index.cgi"+1, X_OK) != 0) + send_headers_and_exit(HTTP_NOT_FOUND); /* no */ + cgi_type = CGI_INDEX; + } #endif + } #if ENABLE_FEATURE_HTTPD_BASIC_AUTH || ENABLE_FEATURE_HTTPD_CGI /* check_user_passwd() would be confused by added .../index.html, truncate it */ |