diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2026-01-22 13:58:28 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2026-01-22 13:58:28 +0100 |
| commit | 851992f070fabcd3d559d67fad6ef642045e6ff0 (patch) | |
| tree | 16b1fc32cdd09b4a3129ab17c8c769b19cf6537b | |
| parent | 649da41ca4cde6d3f56b78170c370045b7857738 (diff) | |
| download | busybox-w32-851992f070fabcd3d559d67fad6ef642045e6ff0.tar.gz busybox-w32-851992f070fabcd3d559d67fad6ef642045e6ff0.tar.bz2 busybox-w32-851992f070fabcd3d559d67fad6ef642045e6ff0.zip | |
httpd: allow http2 requests if proxying, tighten METHOD checks
function old new delta
handle_incoming_and_exit 2264 2312 +48
httpd_main 915 913 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 48/-2) Total: 46 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | networking/httpd.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index 4052cdce0..6b533b473 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
| @@ -2210,6 +2210,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 2210 | #endif | 2210 | #endif |
| 2211 | #if ENABLE_FEATURE_HTTPD_CGI | 2211 | #if ENABLE_FEATURE_HTTPD_CGI |
| 2212 | unsigned total_headers_len; | 2212 | unsigned total_headers_len; |
| 2213 | unsigned un; | ||
| 2213 | #endif | 2214 | #endif |
| 2214 | const char *prequest; | 2215 | const char *prequest; |
| 2215 | static const char request_GET[] ALIGN1 = "GET"; | 2216 | static const char request_GET[] ALIGN1 = "GET"; |
| @@ -2280,14 +2281,12 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 2280 | 2281 | ||
| 2281 | /* Find URL */ | 2282 | /* Find URL */ |
| 2282 | // rfc2616: method and URI is separated by exactly one space | 2283 | // rfc2616: method and URI is separated by exactly one space |
| 2283 | //urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed | 2284 | // no tabs, no double spaces, no empty methods, URIs, etc: |
| 2285 | // should be "METHOD /URI HTTP/xyz" ("\r\n" stripped by get_line) | ||
| 2284 | urlp = strchr(iobuf, ' '); | 2286 | urlp = strchr(iobuf, ' '); |
| 2285 | if (urlp == NULL) | 2287 | if (urlp == NULL) |
| 2286 | send_headers_and_exit(HTTP_BAD_REQUEST); | 2288 | send_headers_and_exit(HTTP_BAD_REQUEST); |
| 2287 | *urlp++ = '\0'; | 2289 | *urlp++ = '\0'; |
| 2288 | //urlp = skip_whitespace(urlp); - should not be necessary | ||
| 2289 | if (urlp[0] != '/') | ||
| 2290 | send_headers_and_exit(HTTP_BAD_REQUEST); | ||
| 2291 | /* Find end of URL */ | 2290 | /* Find end of URL */ |
| 2292 | HTTP_slash = strchr(urlp, ' '); | 2291 | HTTP_slash = strchr(urlp, ' '); |
| 2293 | /* Is it " HTTP/"? */ | 2292 | /* Is it " HTTP/"? */ |
| @@ -2324,26 +2323,34 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 2324 | urlp + strlen(proxy_entry->url_from), /* "SFX" */ | 2323 | urlp + strlen(proxy_entry->url_from), /* "SFX" */ |
| 2325 | HTTP_slash /* "HTTP/xyz" */ | 2324 | HTTP_slash /* "HTTP/xyz" */ |
| 2326 | ); | 2325 | ); |
| 2326 | /* The above also allows http2 which starts with a fixed | ||
| 2327 | * "PRI * HTTP/2.0" line | ||
| 2328 | */ | ||
| 2327 | cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX); | 2329 | cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX); |
| 2328 | } | 2330 | } |
| 2329 | #endif | 2331 | #endif |
| 2332 | /* We don't support http2 "*" URI, enforce "/URI" form */ | ||
| 2333 | if (urlp[0] != '/') | ||
| 2334 | send_headers_and_exit(HTTP_BAD_REQUEST); | ||
| 2330 | 2335 | ||
| 2331 | /* Determine type of request (GET/POST/...) */ | 2336 | /* Determine METHOD of request (GET/POST/...). Case-sensitive (rfc7230,rfc9110) */ |
| 2332 | prequest = request_GET; | 2337 | prequest = request_GET; |
| 2333 | if (strcasecmp(iobuf, prequest) == 0) | 2338 | if (strcmp(iobuf, prequest) == 0) |
| 2334 | goto found; | 2339 | goto found; |
| 2335 | prequest = request_HEAD; | 2340 | prequest = request_HEAD; |
| 2336 | if (strcasecmp(iobuf, prequest) == 0) | 2341 | if (strcmp(iobuf, prequest) == 0) |
| 2337 | goto found; | 2342 | goto found; |
| 2338 | #if !ENABLE_FEATURE_HTTPD_CGI | 2343 | #if !ENABLE_FEATURE_HTTPD_CGI |
| 2339 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); | 2344 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); |
| 2340 | #else | 2345 | #else |
| 2341 | prequest = request_POST; | 2346 | prequest = request_POST; |
| 2342 | if (strcasecmp(iobuf, prequest) == 0) | 2347 | if (strcmp(iobuf, prequest) == 0) |
| 2343 | goto found; | 2348 | goto found; |
| 2344 | /* For CGI, allow DELETE, PUT, OPTIONS, etc too */ | 2349 | /* For CGI, allow DELETE, PUT, OPTIONS, etc too */ |
| 2345 | prequest = alloca(16); | 2350 | prequest = alloca(16); |
| 2346 | safe_strncpy((char*)prequest, iobuf, 16); | 2351 | un = safe_strncpy((char*)prequest, iobuf, 16) - prequest; |
| 2352 | if (un < 1 || un >= 15) | ||
| 2353 | send_headers_and_exit(HTTP_BAD_REQUEST); | ||
| 2347 | #endif | 2354 | #endif |
| 2348 | found: | 2355 | found: |
| 2349 | /* Copy URL to stack-allocated char[] */ | 2356 | /* Copy URL to stack-allocated char[] */ |
