Describe the bug
The Dechunk HTTP response operation does not handle the terminating zero-length chunk defined by RFC 7230, causing trailing metadata to leak into the decoded output.
src/core/operations/DechunkHTTPResponse.mjs, run() method, lines 47-55
while (!isNaN(chunkSize)) {
chunks.push(input.slice(chunkSizeEnd, chunkSize + chunkSizeEnd));
input = input.slice(chunkSizeEnd + chunkSize + lineEndingsLength);
chunkSizeEnd = input.indexOf(lineEndings) + lineEndingsLength;
chunkSize = parseInt(input.slice(0, chunkSizeEnd), 16);
}
return chunks.join("") + input;
A chunked HTTP response is terminated by 0\r\n\r\n, optionally with trailer headers between the two CRLFs. When the loop encounters chunkSize === 0, it does not break — 0 is not NaN, so the loop continues. It pushes an empty string, slices past the zero chunk, and then tries to parse whatever remains (the trailing CRLF or trailer headers) as the next chunk size. That fails with NaN, exiting the loop, but the remaining text is returned verbatim via chunks.join("") + input.
To Reproduce
https://gchq.github.io/CyberChef/#recipe=Dechunk_HTTP_response()&input=NwpNb3ppbGxhCjkKRGV2ZWxvcGVyCjcKTmV0d29yawowCkV4cGlyZXM6IFdlZCwgMjEgT2N0IDIwMTUgMDc6Mjg6MDAgR01UCg
Additional context
Suggested fix:
while (!isNaN(chunkSize)) {
chunks.push(input.slice(chunkSizeEnd, chunkSize + chunkSizeEnd));
input = input.slice(chunkSizeEnd + chunkSize + lineEndingsLength);
chunkSizeEnd = input.indexOf(lineEndings) + lineEndingsLength;
chunkSize = parseInt(input.slice(0, chunkSizeEnd), 16);
if (chunkSize === 0) {
input = input.slice(chunkSizeEnd);
if (input.startsWith(lineEndings)) {
input = input.slice(lineEndingsLength);
}
break;
}
}
return chunks.join("") + input;
This explicitly detects the terminating chunk, consumes it and its trailing CRLF, and breaks out of the loop before the trailer data can be appended to the output.
Describe the bug
The
Dechunk HTTP responseoperation does not handle the terminating zero-length chunk defined by RFC 7230, causing trailing metadata to leak into the decoded output.src/core/operations/DechunkHTTPResponse.mjs,run()method, lines 47-55A chunked HTTP response is terminated by
0\r\n\r\n, optionally with trailer headers between the two CRLFs. When the loop encounterschunkSize === 0, it does not break —0is notNaN, so the loop continues. It pushes an empty string, slices past the zero chunk, and then tries to parse whatever remains (the trailing CRLF or trailer headers) as the next chunk size. That fails withNaN, exiting the loop, but the remaining text is returned verbatim viachunks.join("") + input.To Reproduce
https://gchq.github.io/CyberChef/#recipe=Dechunk_HTTP_response()&input=NwpNb3ppbGxhCjkKRGV2ZWxvcGVyCjcKTmV0d29yawowCkV4cGlyZXM6IFdlZCwgMjEgT2N0IDIwMTUgMDc6Mjg6MDAgR01UCg
Additional context
Suggested fix:
This explicitly detects the terminating chunk, consumes it and its trailing CRLF, and breaks out of the loop before the trailer data can be appended to the output.