Skip to content

feat: harden HTTP request parsing (RFC 7230)#57

Merged
mgrossmann merged 4 commits intomainfrom
issue-10-harden-http-parsing
Apr 11, 2026
Merged

feat: harden HTTP request parsing (RFC 7230)#57
mgrossmann merged 4 commits intomainfrom
issue-10-harden-http-parsing

Conversation

@mgrossmann
Copy link
Copy Markdown
Contributor

Summary

  • Validate HTTP version, Content-Length, header names/values, duplicate Host headers in httpin.c
  • Detect bare CR (without LF) as protocol error in httpgets.c
  • Reject oversized request lines with 414 URI Too Long
  • Return 405 Method Not Allowed for unknown methods instead of 501 (httppars.c)

Acceptance Criteria (from h1spec)

  • Multiple Host headers → 400
  • Non-numeric Content-Length → 400
  • Negative Content-Length → 400
  • Overflowing Content-Length → 400
  • Invalid header characters → 400
  • Control chars in header value → 400
  • Invalid line ending (bare CR) → 400
  • Invalid HTTP version (HTTP/9.9) → 505
  • curl -X PATCH / → 405
  • 8KB URI → 414
  • Existing tests (curl, Zowe CLI, mvsMF) still functional
  • h1spec score: at least 29/33

Test plan

  • Build on MVS (make build && make link)
  • Run h1spec test suite against HTTPD
  • Verify mvsMF API still works (curl dataset/job/uss tests)

Fixes #10

Add validation for HTTP requests in httpin.c and httpgets.c:

- Validate HTTP version (only 1.0/1.1 accepted) → 505
- Reject multiple Host headers → 400
- Validate Content-Length (digits only, non-empty) → 400
- Validate header names (RFC 7230 token chars) → 400
- Reject control characters in header values → 400
- Detect bare CR without LF in httpgets.c → 400
- Reject oversized request lines (buffer full) → 414 URI Too Long

Change unknown HTTP methods from 501 Not Implemented to 405
Method Not Allowed in httppars.c (RFC 7231 §6.5.5).

Fixes #10
When a request has a body (Content-Length or Transfer-Encoding) that
HTTPD doesn't read (unknown method → 405, POST without Content-Type),
the unread body data remains on the socket and corrupts the next
request on a keep-alive connection.

Force Connection: close in these cases to prevent poisoning.
Without a DOCROOT keyword in HTTPPRM, the document root was empty,
causing all static file requests to return 404. Set the default to
/www to match the documented sample configuration.
Switch header name validation from blocklist to allowlist using
isalnum() plus RFC 7230 token special chars. The blocklist approach
failed for [ and ] because CP037 asc2ebc maps ASCII 0x5B/0x5D to
0xBA/0xBB, while c2asm370 compiles '['/']' as 0xAD/0xBD — a code
page mismatch that silently passed invalid characters.

Also send 400 Bad Request when the HTTP version is missing from
the request line (e.g. "GET / \r\n") instead of silently resetting
the connection, which caused h1spec to timeout.
@mgrossmann mgrossmann merged commit 0daf40f into main Apr 11, 2026
1 check failed
@mgrossmann mgrossmann deleted the issue-10-harden-http-parsing branch April 11, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HTTPD] HTTP Request Parsing härten

1 participant