← Commit list

7de0a7e71a

alhudz
alhudz
2026-06-08
SUCCESS Duration: 216s

Subject

chunked: reject invalid bytes in trailer

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/http.c+3 -3
@@ -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;
lib/http.h+5 -0
@@ -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);
lib/http_chunks.c+13 -1
@@ -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 |
tests/data/Makefile.am+1 -1
@@ -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 \
\
tests/data/test2106+53 -0
@@ -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>