TinyWeb HTTP Header Control Character Injection into CGI Environment
Security Advisory. Published: March 4, 2026. Fixed in TinyWeb v2.04 (March 2, 2026).
Summary
TinyWeb HTTP Server version 2.03 and earlier are vulnerable to HTTP header control character injection
into CGI environment variables. The HTTP request header parser did not strictly reject dangerous
control characters such as CR (0x0D), LF (0x0A), and NUL
(0x00) in header values, nor did it reject their percent-encoded forms
(%0d, %0a, %00). When these unsanitized header values are
mapped into HTTP_* CGI environment variables via GetEnvStr, downstream CGI
scripts may interpret injected delimiters, leading to header value confusion, injection into
script-side logic, or bypass of script-side validation.
Severity: High (CVSS 4.0)
Vulnerability Details
| CVE ID | CVE-2026-29046 |
|---|---|
| Vulnerability Type | Improper Neutralization of CRLF Sequences in HTTP Headers (CWE-113), Injection (CWE-74), CRLF Injection (CWE-93), Improper Input Validation (CWE-20) |
| Attack Type | Remote |
| Attack Vector | Network (unauthenticated HTTP request) |
| Vendor/Maintainer | Maxim Masiutin |
| Product | TinyWeb HTTP Server |
| Affected Versions | Version 2.03 and below |
| Fixed Version | 2.04 (March 2, 2026) |
| Impact | Header Confusion at CGI Boundary, Script-side Injection, Validation Bypass |
CVSS Score
| CVSS Version | Score | Severity | Vector String |
|---|---|---|---|
| CVSS 4.0 | 8.8 | High | AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:L/SC:N/SI:H/SA:L |
Technical Details
Root Cause
TinyWeb receives raw HTTP headers, stores them in internal request structures, and then builds CGI
environment strings in GetEnvStr before passing them to CGI script executables.
The header parser did not enforce the following requirements from HTTP standards and security best
practices:
- RFC 9110 and RFC 9112 require robust message parsing and rejection of malformed field lines.
- Obsolete line folding (obs-fold: SP or HTAB at the start of a continued header line) should be rejected for normal HTTP messages.
- Header field values must not contain raw CR/LF line breaks in the parsed value.
- Control characters and NUL should not be accepted in values that cross protocol boundaries.
Because these checks were missing or incomplete, downstream CGI components could interpret injected delimiters differently from the TinyWeb parser, creating a parser differential vulnerability at the CGI boundary.
Affected Code Path
- Client sends an HTTP request with control characters in header values (raw or percent-encoded)
- TinyWeb's header parser accepts the malformed header line without rejection
- The header value is stored in the request structure (e.g.,
TGeneralHeader,TRequestHeader,TEntityHeader) GetEnvStrmaps the unsanitized header value into anHTTP_*CGI environment variable- The CGI script receives tainted environment data that may contain injected delimiters
Exploitation Scenarios
- Header confusion at CGI boundary: Injected CR/LF characters in a header value can cause the CGI script to interpret one header as multiple headers or to see unexpected values.
- Script-side injection: CGI scripts that trust
HTTP_*environment variables without additional sanitization may be vulnerable to injection attacks when these variables contain control characters. - Validation bypass: If a CGI script and TinyWeb interpret header boundaries differently due to embedded control characters, attacker-controlled data may bypass script-side validation checks.
- Reliability degradation: Malformed requests with control characters may cause unpredictable behavior in downstream request processing.
Proof of Concept
The following requests demonstrate inputs that should be rejected with 400 Bad Request
by a properly hardened server:
CRLF Injection via Percent-Encoding
GET /cgi-bin/hello.pl HTTP/1.1 Host: 127.0.0.1 X-Test: ok%0d%0aInjected: yes
The percent-encoded CRLF in the X-Test header value could cause the CGI script to see
an additional Injected: yes environment variable.
NUL Byte in Header Value
GET /cgi-bin/hello.pl HTTP/1.1 Host: 127.0.0.1 X-Test: abc%00def
The NUL byte can cause string truncation in C-based CGI programs that read environment variables, leading to data loss or misinterpretation.
Obsolete Line Folding
GET /cgi-bin/hello.pl HTTP/1.1 Host: 127.0.0.1 Folded: legacy
A header line starting with whitespace (obs-fold) should be rejected per RFC 9112 requirements.
Expected secure behavior: The server returns 400 Bad Request, the
request is not forwarded to CGI, and no unsafe HTTP_* environment variable is
created.
Fix Applied in Version 2.04
The problem has been patched in version 2.04 by implementing strict header
validation in SrvMain.pas:
- Control character rejection: Any header line containing raw NUL
(
#0), CR (#13), or LF (#10) bytes is rejected immediately with HTTP 400. (Commit 53aa8b6) - Obs-fold rejection: Header continuation lines starting with SP or HTAB (obsolete line folding per RFC 9112) are rejected.
- Encoded control character rejection: Percent-encoded dangerous octets
(
%00,%0d,%0a, case-insensitive) in header values are detected and rejected. - Strict header name grammar: Header names are validated to contain only
tcharcharacters as defined by RFC 9110. - CGI boundary protection: Rejected requests do not enter CGI environment
construction (
GetEnvStr), ensuring no tainted data reaches CGI scripts.
Workarounds
If upgrading to v2.04 is not immediately possible, consider the following mitigations:
- Place TinyWeb behind a reverse proxy (nginx, Apache, HAProxy) that validates and normalizes HTTP headers before forwarding. Most modern reverse proxies reject headers containing control characters by default.
- Use a Web Application Firewall (WAF) configured to block requests with percent-encoded control
characters (
%00,%0d,%0a) in header values. - Ensure CGI scripts independently validate all
HTTP_*environment variables and reject values containing control characters.
Timeline
| March 2, 2026 | Vulnerability identified by Maxim Masiutin |
|---|---|
| March 2, 2026 | Fix implemented and committed to master |
| March 4, 2026 | Security advisory published (CVE-2026-29046) |
References
- TinyWeb GitHub Repository
- Fix Commit (GitHub)
- CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers
- CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (Injection)
- CWE-93: Improper Neutralization of CRLF Sequences (CRLF Injection)
- CWE-20: Improper Input Validation
- RFC 9110: HTTP Semantics
- RFC 9112: HTTP/1.1 Message Syntax and Routing
- RFC 3875: The Common Gateway Interface (CGI) Version 1.1
Other TinyWeb CVEs
| CVE-2026-27633 | Content-Length Memory Exhaustion (CWE-400) - Fixed in v2.02. CVSS 8.7 High. Advisory |
|---|---|
| CVE-2026-27630 | Thread/Connection Exhaustion Slowloris (CWE-400) - Fixed in v2.02. CVSS 8.7 High. Advisory |
| CVE-2026-27613 | CGI Parameter Injection (CWE-78, CWE-88) - Fixed in v2.01. CVSS 9.3 Critical. Advisory |
| CVE-2024-5193 | CRLF Injection (CWE-93) - Fixed in v1.99. CVSS 5.3 Medium. Advisory |
| CVE-2024-34199 | Buffer Overflow (CWE-787) - Fixed in v1.99. CVSS 8.6 High. Advisory |
| CVE-2004-2636 | Path Traversal (CWE-22) - Fixed in v1.93. CVSS 5.0 Medium. Advisory |
| CVE-2003-1510 | Denial of Service (CWE-400) - Fixed in v1.93. CVSS 7.8 High. Advisory |