Skip to content

Avoid UB trimming empty response header values - #749

Closed
mcc0nnell wants to merge 1 commit into
apache:trunkfrom
mcc0nnell:fix/empty-header-trim-ub
Closed

Avoid UB trimming empty response header values#749
mcc0nnell wants to merge 1 commit into
apache:trunkfrom
mcc0nnell:fix/empty-header-trim-ub

Conversation

@mcc0nnell

@mcc0nnell mcc0nnell commented Sep 9, 2026

Copy link
Copy Markdown

Several response/header parsing paths trim trailing whitespace by first forming a pointer to strlen(value) - 1. For an empty string, that constructs a pointer before the start of the object before the loop condition can reject it.

This change adds ap_cstr_stripws(char *) in server/util.c and declares it in include/httpd.h. The helper uses an end-exclusive pointer, so empty and all-whitespace strings are handled without underflow.

The duplicated trailing-whitespace logic is replaced in:

  • mod_proxy_http
  • mod_proxy_uwsgi
  • mod_proxy_hcheck
  • server/util_script.c
  • mod_cern_meta
  • cfg_trim_line()
  • byterange_filter
  • mod_negotiation

Coverage includes unit cases for empty strings, all-whitespace strings, ordinary values, trailing whitespace, and preservation of leading whitespace. The proxy regression tests also retain backend responses containing a valid empty X-Empty: header for both HTTP proxy and uWSGI paths.

Validation on the current branch in a clean Ubuntu 24.04 container:

  • full httpd build succeeds with the affected modules enabled
  • httpdunit passes 60/60, including all seven ap_cstr_stripws() cases
  • test_03_response.py and test_05_uwsgi.py pass 6/6, including the HTTP proxy and uWSGI empty-header regressions
  • git diff --check: clean
  • modified Python regression files compile cleanly with py_compile

I have not demonstrated a crash, out-of-bounds read/write, information disclosure, or other exploit primitive; this remains a narrow UB hardening change.

@notroj

notroj commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Nice find. Could you add an ap_cstr_stripws to server/util.c (or maybe a better name comes to mind) - given the prevalence of the error?

@mcc0nnell
mcc0nnell force-pushed the fix/empty-header-trim-ub branch from a078a56 to 7487dd0 Compare September 13, 2026 15:22
@mcc0nnell

Copy link
Copy Markdown
Author

Thanks — added ap_cstr_stripws() in server/util.c, declared it in httpd.h, and switched the affected callers over to it. I also added focused unit coverage for empty/all-whitespace/trailing-whitespace cases and converted three additional instances of the same underflow-prone trimming idiom. The existing proxy regressions remain in place.

@mcc0nnell
mcc0nnell force-pushed the fix/empty-header-trim-ub branch from 1e49451 to 670117c Compare September 13, 2026 17:40
@mcc0nnell

Copy link
Copy Markdown
Author

Fresh validation on the current single-commit head is clean: full Ubuntu 24.04 build succeeds, httpdunit passes 60/60 (including all 7 ap_cstr_stripws() cases), and the HTTP proxy + uWSGI regression files pass 6/6 including both empty-header cases. git diff --check and py_compile are clean as well. I updated the PR description with the current results.

@notroj

notroj commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Thanks, great stuff. I adjusted it here to return the end pointer and do some housekeeping.

trunk...notroj:httpd:pr749-copy

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.

2 participants