Search
Find a vulnerability
Search criteria
1 vulnerability found for WatsonWebserver by unknown
GCVE-1988-2026-0076
Vulnerability from gna-1988 – Published: 2026-09-07 13:20 – Updated: 2026-09-07 13:20
VLAI
EPSS
VEX
Title
WatsonWebserver v7.1.0 HTTP/1 Chunked Request Processing Bypasses MaxRequestBodySize
Summary
WatsonWebserver contains an HTTP/1 request body size-limit bypass when
processing requests using Transfer-Encoding: chunked.
The framework's configured Settings.IO.MaxRequestBodySize limit is enforced
when a request declares its body size using Content-Length. However,
requests using chunked transfer encoding are processed through a separate
body-reading path that accumulates decoded chunks into a MemoryStream
without enforcing the same cumulative request-body limit.
As a result, a remote client can submit an HTTP/1 request whose decoded
body exceeds the administrator-configured MaxRequestBodySize by using
chunked transfer encoding instead of Content-Length.
A proof of concept configured:
MaxRequestBodySize = 16 bytes
and submitted a chunked request containing:
24 bytes
of decoded body data.
WatsonWebserver accepted the complete request, delivered all 24 bytes to
the application, and returned:
HTTP/1.1 200 OK
len=24
This confirms that MaxRequestBodySize is not consistently enforced across
supported HTTP/1 request-framing mechanisms.
Because the chunked body is accumulated in memory without a cumulative
MaxRequestBodySize check, an attacker may also be able to cause excessive
memory and CPU consumption by submitting substantially larger request
bodies. The supplied PoC directly demonstrates the size-limit bypass;
denial of service is a potential consequence rather than a demonstrated
result of the 24-byte test.
Vulnerability Description
WatsonWebserver provides the following configuration setting for
restricting HTTP request body size:
Settings.IO.MaxRequestBodySize
For HTTP/1 requests containing a Content-Length header, WatsonWebserver
parses the declared body size and rejects the request when it exceeds the
configured maximum.
However, HTTP/1 also permits request bodies to be framed using:
Transfer-Encoding: chunked
Chunked requests do not contain a single up-front Content-Length. Instead,
the body is transmitted as a sequence of independently sized chunks.
WatsonWebserver handles these requests through ReadChunkedBodyAsync(),
which repeatedly reads chunks and writes their contents into an in-memory
MemoryStream.
The implementation does not maintain a cumulative decoded-body length and
does not compare the accumulated size against Settings.IO.MaxRequestBodySize
.
Consequently, a client can bypass the configured request body limit simply
by changing the HTTP framing mechanism from Content-Length to
Transfer-Encoding:
chunked.
Technical AnalysisContent-Length Path
When WatsonWebserver encounters a request containing Content-Length, the
parsed length is stored in:
metadata.ContentLength = parsedContentLength;
The framework subsequently enforces MaxRequestBodySize:
if (settings.IO.MaxRequestBodySize > 0 &&
metadata.ContentLength > settings.IO.MaxRequestBodySize)
{
throw new IOException(
"Request body size "
+ metadata.ContentLength
+ " exceeds maximum allowed size "
+ settings.IO.MaxRequestBodySize
+ ".");
}
The configured maximum is therefore enforced for requests whose body
length is known through Content-Length.
Chunked Request Path
Requests using:
Transfer-Encoding: chunked
follow a different body-processing path.
The relevant implementation is:
private async Task<byte[]> ReadChunkedBodyAsync(
CancellationToken token)
{
using (MemoryStream memoryStream = new MemoryStream())
{
while (true)
{
Chunk chunk =
await ReadChunk(token)
.ConfigureAwait(false);
if (chunk.Data != null &&
chunk.Data.Length > 0)
{
memoryStream.Write(
chunk.Data,
0,
chunk.Data.Length);
}
if (chunk.IsFinal)
break;
}
_BodyComplete = true;
return memoryStream.ToArray();
}
}
Each decoded chunk is appended directly to the MemoryStream:
memoryStream.Write(
chunk.Data,
0,
chunk.Data.Length);
There is no equivalent check against:
Settings.IO.MaxRequestBodySize
before the write.
The loop continues until the terminating chunk is received.
Proof of ConceptServer Configuration
The proof of concept configures WatsonWebserver with:
server.Settings.IO.MaxRequestBodySize = 16;
The maximum accepted request body should therefore be:
16 bytes
Malicious Request
The client submits a valid chunked HTTP/1 request:
POST / HTTP/1.1
Host: 127.0.0.1
Transfer-Encoding: chunked
Connection: close
8
abcdefgh
8
ijklmnop
8
qrstuvwx
0
The request contains three chunks.
Each chunk contains:
8 bytes
giving a cumulative decoded request body of:
8 + 8 + 8 = 24 bytes
The body therefore exceeds the configured limit by:
24 - 16 = 8 bytes
or:
150% of the configured maximum.
Observed HTTP Response
WatsonWebserver accepts the request and returns:
HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 6 Date: Thu, 06
Aug 2026 01:16:34 GMT Connection: close Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, HEAD, GET, PUT, POST, DELETE, PATCH
Access-Control-Allow-Headers: * Access-Control-Expose-Headers: Accept: */*
Accept-Language: en-US, en Accept-Charset: ISO-8859-1, utf-8 Cache-Control:
no-cache Host: 127.0.0.1:44009 len=24
The application reports:
len=24
confirming that the complete decoded body reached the application despite:
MaxRequestBodySize = 16
Security ImpactConfirmed Impact
The PoC directly demonstrates that a remote HTTP client can bypass the
configured:
Settings.IO.MaxRequestBodySize
restriction when using chunked transfer encoding.
The confirmed impact is therefore:
- bypass of the configured HTTP request-body size restriction;
- acceptance of request bodies larger than the administrator-defined
maximum; and
- in-memory processing of data that should have been rejected by the
configured limit.
Resource Consumption
The affected chunked path accumulates the decoded body in a MemoryStream:
memoryStream.Write(
chunk.Data,
0,
chunk.Data.Length);
and ultimately performs:
return memoryStream.ToArray();
Because there is no cumulative MaxRequestBodySize check in this path,
substantially larger request bodies can potentially consume increasing
amounts of process memory and processing time.
Depending on deployment configuration, available resources, concurrency,
reverse proxies, transport timeouts, and application-specific controls,
this may contribute to:
- excessive memory consumption;
- increased CPU utilization;
- request-processing degradation; and
- denial of service.
The supplied 24-byte PoC demonstrates the *security-control bypass*, not
resource exhaustion itself.
Ron Edgerson
Vulnerability Researcher & Exploit Developer
CVE Research | Binary Exploitation | Application & Systems Security
Responsible Disclosure • Proof-of-Concept Development
🌐 https://github.com/ob1sec
🔗 https://www.linkedin.com/in/ronedgerson1
<https://linkedin.com/in/yourhandle>
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Severity
No CVSS data available.
Assigner
References
7 references
Impacted products
1 product
| Vendor | Product | Version | |
|---|---|---|---|
| unknown | WatsonWebserver |
Affected:
unknown
|
{
"containers": {
"cna": {
"affected": [
{
"product": "WatsonWebserver",
"vendor": "unknown",
"versions": [
{
"status": "affected",
"version": "unknown"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Ron E"
}
],
"descriptions": [
{
"lang": "en",
"value": "WatsonWebserver contains an HTTP/1 request body size-limit bypass when\nprocessing requests using Transfer-Encoding: chunked.\n\nThe framework\u0027s configured Settings.IO.MaxRequestBodySize limit is enforced\nwhen a request declares its body size using Content-Length. However,\nrequests using chunked transfer encoding are processed through a separate\nbody-reading path that accumulates decoded chunks into a MemoryStream\nwithout enforcing the same cumulative request-body limit.\n\nAs a result, a remote client can submit an HTTP/1 request whose decoded\nbody exceeds the administrator-configured MaxRequestBodySize by using\nchunked transfer encoding instead of Content-Length.\n\nA proof of concept configured:\n\nMaxRequestBodySize = 16 bytes\n\nand submitted a chunked request containing:\n\n24 bytes\n\nof decoded body data.\n\nWatsonWebserver accepted the complete request, delivered all 24 bytes to\nthe application, and returned:\n\nHTTP/1.1 200 OK\n\nlen=24\n\nThis confirms that MaxRequestBodySize is not consistently enforced across\nsupported HTTP/1 request-framing mechanisms.\n\nBecause the chunked body is accumulated in memory without a cumulative\nMaxRequestBodySize check, an attacker may also be able to cause excessive\nmemory and CPU consumption by submitting substantially larger request\nbodies. The supplied PoC directly demonstrates the size-limit bypass;\ndenial of service is a potential consequence rather than a demonstrated\nresult of the 24-byte test.\n\n\nVulnerability Description\n\nWatsonWebserver provides the following configuration setting for\nrestricting HTTP request body size:\n\nSettings.IO.MaxRequestBodySize\n\nFor HTTP/1 requests containing a Content-Length header, WatsonWebserver\nparses the declared body size and rejects the request when it exceeds the\nconfigured maximum.\n\nHowever, HTTP/1 also permits request bodies to be framed using:\n\nTransfer-Encoding: chunked\n\nChunked requests do not contain a single up-front Content-Length. Instead,\nthe body is transmitted as a sequence of independently sized chunks.\n\nWatsonWebserver handles these requests through ReadChunkedBodyAsync(),\nwhich repeatedly reads chunks and writes their contents into an in-memory\nMemoryStream.\n\nThe implementation does not maintain a cumulative decoded-body length and\ndoes not compare the accumulated size against Settings.IO.MaxRequestBodySize\n.\n\nConsequently, a client can bypass the configured request body limit simply\nby changing the HTTP framing mechanism from Content-Length to\nTransfer-Encoding:\nchunked.\n\n\nTechnical AnalysisContent-Length Path\n\nWhen WatsonWebserver encounters a request containing Content-Length, the\nparsed length is stored in:\n\nmetadata.ContentLength = parsedContentLength;\n\nThe framework subsequently enforces MaxRequestBodySize:\n\nif (settings.IO.MaxRequestBodySize \u003e 0 \u0026\u0026\n metadata.ContentLength \u003e settings.IO.MaxRequestBodySize)\n{\n throw new IOException(\n \"Request body size \"\n + metadata.ContentLength\n + \" exceeds maximum allowed size \"\n + settings.IO.MaxRequestBodySize\n + \".\");\n}\n\nThe configured maximum is therefore enforced for requests whose body\nlength is known through Content-Length.\n\n\nChunked Request Path\n\nRequests using:\n\nTransfer-Encoding: chunked\n\nfollow a different body-processing path.\n\nThe relevant implementation is:\n\nprivate async Task\u003cbyte[]\u003e ReadChunkedBodyAsync(\n CancellationToken token)\n{\n using (MemoryStream memoryStream = new MemoryStream())\n {\n while (true)\n {\n Chunk chunk =\n await ReadChunk(token)\n .ConfigureAwait(false);\n\n if (chunk.Data != null \u0026\u0026\n chunk.Data.Length \u003e 0)\n {\n memoryStream.Write(\n chunk.Data,\n 0,\n chunk.Data.Length);\n }\n\n if (chunk.IsFinal)\n break;\n }\n\n _BodyComplete = true;\n\n return memoryStream.ToArray();\n }\n}\n\nEach decoded chunk is appended directly to the MemoryStream:\n\nmemoryStream.Write(\n chunk.Data,\n 0,\n chunk.Data.Length);\n\nThere is no equivalent check against:\n\nSettings.IO.MaxRequestBodySize\n\nbefore the write.\n\nThe loop continues until the terminating chunk is received.\n\n\nProof of ConceptServer Configuration\n\nThe proof of concept configures WatsonWebserver with:\n\nserver.Settings.IO.MaxRequestBodySize = 16;\n\nThe maximum accepted request body should therefore be:\n\n16 bytes\n\nMalicious Request\n\nThe client submits a valid chunked HTTP/1 request:\n\nPOST / HTTP/1.1\nHost: 127.0.0.1\nTransfer-Encoding: chunked\nConnection: close\n\n8\nabcdefgh\n8\nijklmnop\n8\nqrstuvwx\n0\n\nThe request contains three chunks.\n\nEach chunk contains:\n\n8 bytes\n\ngiving a cumulative decoded request body of:\n\n8 + 8 + 8 = 24 bytes\n\nThe body therefore exceeds the configured limit by:\n\n24 - 16 = 8 bytes\n\nor:\n\n150% of the configured maximum.\n\nObserved HTTP Response\n\nWatsonWebserver accepts the request and returns:\nHTTP/1.1 200 OK Content-Type: text/plain Content-Length: 6 Date: Thu, 06\nAug 2026 01:16:34 GMT Connection: close Access-Control-Allow-Origin: *\nAccess-Control-Allow-Methods: OPTIONS, HEAD, GET, PUT, POST, DELETE, PATCH\nAccess-Control-Allow-Headers: * Access-Control-Expose-Headers: Accept: */*\nAccept-Language: en-US, en Accept-Charset: ISO-8859-1, utf-8 Cache-Control:\nno-cache Host: 127.0.0.1:44009 len=24\n\nThe application reports:\nlen=24\n\nconfirming that the complete decoded body reached the application despite:\nMaxRequestBodySize = 16\n\nSecurity ImpactConfirmed Impact\n\nThe PoC directly demonstrates that a remote HTTP client can bypass the\nconfigured:\n\nSettings.IO.MaxRequestBodySize\n\nrestriction when using chunked transfer encoding.\n\nThe confirmed impact is therefore:\n\n - bypass of the configured HTTP request-body size restriction;\n - acceptance of request bodies larger than the administrator-defined\n maximum; and\n - in-memory processing of data that should have been rejected by the\n configured limit.\n\nResource Consumption\n\nThe affected chunked path accumulates the decoded body in a MemoryStream:\n\nmemoryStream.Write(\n chunk.Data,\n 0,\n chunk.Data.Length);\n\nand ultimately performs:\n\nreturn memoryStream.ToArray();\n\nBecause there is no cumulative MaxRequestBodySize check in this path,\nsubstantially larger request bodies can potentially consume increasing\namounts of process memory and processing time.\n\nDepending on deployment configuration, available resources, concurrency,\nreverse proxies, transport timeouts, and application-specific controls,\nthis may contribute to:\n\n - excessive memory consumption;\n - increased CPU utilization;\n - request-processing degradation; and\n - denial of service.\n\nThe supplied 24-byte PoC demonstrates the *security-control bypass*, not\nresource exhaustion itself.\n\nRon Edgerson\nVulnerability Researcher \u0026 Exploit Developer\n\nCVE Research | Binary Exploitation | Application \u0026 Systems Security\nResponsible Disclosure \u2022 Proof-of-Concept Development\n\n\ud83c\udf10 https://github.com/ob1sec\n\ud83d\udd17 https://www.linkedin.com/in/ronedgerson1\n\u003chttps://linkedin.com/in/yourhandle\u003e\n_______________________________________________\nSent through the Full Disclosure mailing list\nhttps://nmap.org/mailman/listinfo/fulldisclosure\nWeb Archives \u0026 RSS: https://seclists.org/fulldisclosure/"
}
],
"providerMetadata": {
"dateUpdated": "2026-09-07T13:20:21Z",
"orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"shortName": "VULNARCHIVE"
},
"references": [
{
"tags": [
"technical-description"
],
"url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Aug/104"
},
{
"tags": [
"technical-description"
],
"url": "https://seclists.org/fulldisclosure/2026/Aug/104"
},
{
"url": "https://github.com/ob1sec"
},
{
"url": "https://linkedin.com/in/yourhandle"
},
{
"url": "https://nmap.org/mailman/listinfo/fulldisclosure"
},
{
"url": "https://seclists.org/fulldisclosure/"
},
{
"url": "https://www.linkedin.com/in/ronedgerson1"
}
],
"source": {
"defect": [
"https://seclists.org/fulldisclosure/2026/Aug/104"
],
"discovery": "EXTERNAL"
},
"title": "WatsonWebserver v7.1.0 HTTP/1 Chunked Request Processing Bypasses MaxRequestBodySize",
"x_gcve": [
{
"recordType": "advisory",
"relationships": [],
"vulnId": "GCVE-1988-2026-0076",
"x_vulnarchive": {
"archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Aug/104",
"automated": true,
"contentSha256": "38816a813b8254c012b7c96eff0335ea6f0b2235d94514fcdf34162ca1e1d896",
"evidenceScore": 7,
"messageId": "",
"originalUrl": "https://seclists.org/fulldisclosure/2026/Aug/104",
"policy": "vulnarchive-1",
"sourceFormat": "text/html",
"sourcePublishedAt": "2026-08-22T12:43:02Z"
}
}
]
}
},
"cveMetadata": {
"assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"assignerShortName": "VULNARCHIVE",
"datePublished": "2026-09-07T13:20:21Z",
"dateUpdated": "2026-09-07T13:20:21Z",
"state": "PUBLISHED",
"vulnId": "GCVE-1988-2026-0076"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}