chunked: reject invalid bytes in trailer
No binary (build failed)
—
(log yok)
| @@ -3808,8 +3808,8 @@ static CURLcode http_size(struct Curl_easy *data) | |
| return CURLE_OK; | |
| } | |
| - | static CURLcode verify_header(struct Curl_easy *data, |
| - | const char *hd, size_t hdlen) |
| + | CURLcode Curl_verify_header(struct Curl_easy *data, |
| + | const char *hd, size_t hdlen) |
| { | |
| struct SingleRequest *k = &data->req; | |
| const char *ptr = memchr(hd, 0x00, hdlen); | |
| @@ -4359,7 +4359,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, | |
| } | |
| } | |
| - | result = verify_header(data, hd, hdlen); |
| + | result = Curl_verify_header(data, hd, hdlen); |
| if(result) | |
| return result; | |
| @@ -106,6 +106,11 @@ CURLcode Curl_http_write_resp_hd(struct Curl_easy *data, | |
| const char *hd, size_t hdlen, | |
| bool is_eos); | |
| + | /* check a received header line for forbidden bytes/format, the same checks |
| + | applied to regular response headers */ |
| + | CURLcode Curl_verify_header(struct Curl_easy *data, |
| + | const char *hd, size_t hdlen); |
| + | |
| /* These functions are in http.c */ | |
| CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, | |
| const char *auth); | |
| @@ -27,6 +27,7 @@ | |
| #include "urldata.h" /* it includes http_chunks.h */ | |
| #include "curl_trc.h" | |
| + | #include "http.h" /* for Curl_verify_header */ |
| #include "sendf.h" /* for the client write stuff */ | |
| #include "curlx/dynbuf.h" | |
| #include "multiif.h" | |
| @@ -247,6 +248,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, | |
| there was no trailer and we move on */ | |
| if(tr) { | |
| + | size_t trlen; |
| result = curlx_dyn_addn(&ch->trailer, STRCONST("\x0d\x0a")); | |
| if(result) { | |
| ch->state = CHUNK_FAILED; | |
| @@ -254,8 +256,18 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, | |
| return result; | |
| } | |
| tr = curlx_dyn_ptr(&ch->trailer); | |
| + | trlen = curlx_dyn_len(&ch->trailer); |
| + | |
| + | /* a trailer is delivered to the client as a header, so it must pass |
| + | the same checks as a regular response header */ |
| + | result = Curl_verify_header(data, tr, trlen); |
| + | if(result) { |
| + | ch->state = CHUNK_FAILED; |
| + | ch->last_code = CHUNKE_BAD_CHUNK; |
| + | return result; |
| + | } |
| + | |
| if(!data->set.http_te_skip) { | |
| - | size_t trlen = curlx_dyn_len(&ch->trailer); |
| if(cw_next) | |
| result = Curl_cwriter_write(data, cw_next, | |
| CLIENTWRITE_HEADER | | |
| @@ -253,7 +253,7 @@ test2064 test2065 test2066 test2067 test2068 test2069 test2070 test2071 \ | |
| test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 \ | |
| test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 \ | |
| test2088 test2089 test2090 test2091 test2092 \ | |
| - | test2100 test2101 test2102 test2103 test2104 test2105 \ |
| + | test2100 test2101 test2102 test2103 test2104 test2105 test2106 \ |
| \ | |
| test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 \ | |
| \ | |
| @@ -0,0 +1,53 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | HTTP |
| + | HTTP GET |
| + | chunked Transfer-Encoding |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Server-side |
| + | <reply> |
| + | <data nocheck="yes"> |
| + | HTTP/1.1 200 OK%CR |
| + | Server: test%CR |
| + | Transfer-Encoding: chunked%CR |
| + | Trailer: chunky-trailer%CR |
| + | %CR |
| + | 6%CR |
| + | -foo-%CR |
| + | 0%CR |
| + | chunky-trailer: he%hex[%00]hex%llo%CR |
| + | %CR |
| + | </data> |
| + | </reply> |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | http |
| + | </server> |
| + | <name> |
| + | HTTP chunked response with a nul byte in the trailer |
| + | </name> |
| + | <command> |
| + | http://%HOSTIP:%HTTPPORT/%TESTNUMBER |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <protocol crlf="headers"> |
| + | GET /%TESTNUMBER HTTP/1.1 |
| + | Host: %HOSTIP:%HTTPPORT |
| + | User-Agent: curl/%VERSION |
| + | Accept: */* |
| + | |
| + | </protocol> |
| + | <errorcode> |
| + | 8 |
| + | </errorcode> |
| + | </verify> |
| + | </testcase> |