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

  1. Client sends an HTTP request with control characters in header values (raw or percent-encoded)
  2. TinyWeb's header parser accepts the malformed header line without rejection
  3. The header value is stored in the request structure (e.g., TGeneralHeader, TRequestHeader, TEntityHeader)
  4. GetEnvStr maps the unsanitized header value into an HTTP_* CGI environment variable
  5. 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 tchar characters 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

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