From 3253d7fe0097ff15797ee4918e927b0c9d6863a9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 28 Mar 2023 18:53:07 +0200 Subject: 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 --- networking/httpd.c | 74 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'networking') 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 / 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 / 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 */ -- cgit v1.1