CVE-2026-119618 (CRITICAL): Apache mod_http2 assign_headers() heap corruption -> RCE, httpd 2.4.55-2.4.70, fixed upstream in 2.4.71. AlmaLinux has no fixed httpd yet (EL10 httpd-2.4.63-13.el10_2.8 has no fix), so rebuilding cannot remove the code. Our default config already does not negotiate h2 (no Protocols directive), this makes it structurally impossible (defense in depth). Nothing in WHP needs HTTP/2 or mod_md inside a container: the HAProxy edge terminates h2/h3 and speaks HTTP/1.1 to backends, and Let's Encrypt is done by the edge. (Also fixes the CVE-2026-106023 mod_md crash surface: mod_md is not installed on EL10 at all.)
Changes
scripts/httpd-h2-md-gate.sh (new): remove uninstalls the mod_http2 / mod_md RPMs if present (mod_http2 is a separate package, nothing requires it; dnf remove --assumeno showed it removes only that 1 package and keeps httpd). check fails the build if rpm -q mod_http2|mod_md succeeds, httpd -M lists http2_module/proxy_http2_module/md_module (anchored, so systemd_module does not match), or httpd -t fails; writes /etc/whp-httpd-version.
Dockerfile (cac php82-85, also form-sender base), Dockerfile.shared-httpd, Dockerfile.fpm: final RUN gate remove && gate check (after all package steps) and LABEL org.whp.httpd-h2-md="removed". cac-fpm only has httpd-core (no mod_http2) so it is gate-only.
Removed files (via the RPM): /etc/httpd/conf.modules.d/10-h2.conf, 10-proxy_h2.conf, mod_http2.so, mod_proxy_http2.so.
.gitea/workflows/build-push.yaml: gate script added to the shellcheck list.
Audit: httpd version per image = docker run --rm --entrypoint cat IMG /etc/whp-httpd-version (a LABEL cannot hold a value computed in a RUN; the static label marks hardened images).
No http2/Protocols/MDomain/h2:// reference exists in this repo's configs/scripts; none in the WHP repo's Apache templates (only the Go panel's own HTTP/2 server and docs).
Verified locally (amd64; arm64 build of shared-httpd also passes, gate OK under qemu)
cac php85, shared-httpd, cac-fpm php83 built; gate OK in each; httpd -M has none of the 3 modules, httpd -t Syntax OK; HTTP/1.1 requests served (cac: 200 over https/1.1 with --http2 negotiating 1.1); h2c prior-knowledge fails; shared-httpd listens :80/:443 and behaves identically to the current image. Negative test: gate run against the current published cac:php83 exits 1.
NOT verified: the real CI run, the pkg-cache path, cac-litespeed/OLS images (not Apache, untouched).
IMPORTANT: merging triggers a full rebuild
build-push.yaml runs on push to trunk and publishes the whole matrix (cac, cac-fpm, litespeed, shared-httpd, ...). That is intended (all images refreshed). Pushing this branch does not publish anything.
Before merging, record rollback digests for every tag:
for i in cac:php82 cac:php83 cac:php84 cac:php85 cac:latest cac-fpm:php82 cac-fpm:php83 cac-fpm:php84 cac-fpm:php85 cac-fpm:latest shared-httpd:latest; do echo "$i $(docker buildx imagetools inspect repo.anhonesthost.net/cloud-hosting-platform/$i --format '{{.Manifest.Digest}}')"; done
After merge verify: every Build job green; on a canary pull, httpd -M | grep -E '^ (http2|proxy_http2|md)_module' empty, cat /etc/whp-httpd-version, sites load (test server first), then roll fleet. Rollback = retag the recorded digest. Rebuild again when Alma ships httpd 2.4.71 (module removal can stay).
## Why
CVE-2026-119618 (CRITICAL): Apache mod_http2 `assign_headers()` heap corruption -> RCE, httpd 2.4.55-2.4.70, fixed upstream in 2.4.71. AlmaLinux has no fixed httpd yet (EL10 httpd-2.4.63-13.el10_2.8 has no fix), so rebuilding cannot remove the code. Our default config already does not negotiate h2 (no `Protocols` directive), this makes it structurally impossible (defense in depth). Nothing in WHP needs HTTP/2 or mod_md inside a container: the HAProxy edge terminates h2/h3 and speaks HTTP/1.1 to backends, and Let's Encrypt is done by the edge. (Also fixes the CVE-2026-106023 mod_md crash surface: mod_md is not installed on EL10 at all.)
## Changes
- `scripts/httpd-h2-md-gate.sh` (new): `remove` uninstalls the `mod_http2` / `mod_md` RPMs if present (`mod_http2` is a separate package, nothing requires it; `dnf remove --assumeno` showed it removes only that 1 package and keeps httpd). `check` fails the build if `rpm -q mod_http2|mod_md` succeeds, `httpd -M` lists `http2_module`/`proxy_http2_module`/`md_module` (anchored, so `systemd_module` does not match), or `httpd -t` fails; writes `/etc/whp-httpd-version`.
- `Dockerfile` (cac php82-85, also form-sender base), `Dockerfile.shared-httpd`, `Dockerfile.fpm`: final `RUN gate remove && gate check` (after all package steps) and `LABEL org.whp.httpd-h2-md="removed"`. cac-fpm only has httpd-core (no mod_http2) so it is gate-only.
- Removed files (via the RPM): `/etc/httpd/conf.modules.d/10-h2.conf`, `10-proxy_h2.conf`, `mod_http2.so`, `mod_proxy_http2.so`.
- `.gitea/workflows/build-push.yaml`: gate script added to the shellcheck list.
- Audit: httpd version per image = `docker run --rm --entrypoint cat IMG /etc/whp-httpd-version` (a LABEL cannot hold a value computed in a RUN; the static label marks hardened images).
- No http2/`Protocols`/`MDomain`/`h2://` reference exists in this repo's configs/scripts; none in the WHP repo's Apache templates (only the Go panel's own HTTP/2 server and docs).
## Verified locally (amd64; arm64 build of shared-httpd also passes, gate OK under qemu)
cac php85, shared-httpd, cac-fpm php83 built; gate OK in each; `httpd -M` has none of the 3 modules, `httpd -t` Syntax OK; HTTP/1.1 requests served (cac: 200 over https/1.1 with `--http2` negotiating 1.1); h2c prior-knowledge fails; shared-httpd listens :80/:443 and behaves identically to the current image. Negative test: gate run against the current published `cac:php83` exits 1.
NOT verified: the real CI run, the pkg-cache path, `cac-litespeed`/OLS images (not Apache, untouched).
## IMPORTANT: merging triggers a full rebuild
`build-push.yaml` runs on push to `trunk` and publishes the whole matrix (cac, cac-fpm, litespeed, shared-httpd, ...). That is intended (all images refreshed). Pushing this branch does not publish anything.
Before merging, record rollback digests for every tag:
```
for i in cac:php82 cac:php83 cac:php84 cac:php85 cac:latest cac-fpm:php82 cac-fpm:php83 cac-fpm:php84 cac-fpm:php85 cac-fpm:latest shared-httpd:latest; do echo "$i $(docker buildx imagetools inspect repo.anhonesthost.net/cloud-hosting-platform/$i --format '{{.Manifest.Digest}}')"; done
```
After merge verify: every Build job green; on a canary pull, `httpd -M | grep -E '^ (http2|proxy_http2|md)_module'` empty, `cat /etc/whp-httpd-version`, sites load (test server first), then roll fleet. Rollback = retag the recorded digest. Rebuild again when Alma ships httpd 2.4.71 (module removal can stay).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
mod_http2 (httpd 2.4.55-2.4.70) assign_headers() heap corruption -> RCE;
AlmaLinux has no fixed httpd yet. Nothing in WHP uses HTTP/2 inside a
container (HAProxy edge terminates h2/h3 and speaks HTTP/1.1 to backends),
so uninstall mod_http2 (and mod_md if ever present) from cac, cac-fpm and
shared-httpd. scripts/httpd-h2-md-gate.sh fails the build if http2_module,
proxy_http2_module or md_module is loadable or `httpd -t` fails, writes
/etc/whp-httpd-version and the images get LABEL org.whp.httpd-h2-md=removed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
jknapp
merged commit 1c9b0edeca into trunk2026-11-12 14:01:07 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why
CVE-2026-119618 (CRITICAL): Apache mod_http2
assign_headers()heap corruption -> RCE, httpd 2.4.55-2.4.70, fixed upstream in 2.4.71. AlmaLinux has no fixed httpd yet (EL10 httpd-2.4.63-13.el10_2.8 has no fix), so rebuilding cannot remove the code. Our default config already does not negotiate h2 (noProtocolsdirective), this makes it structurally impossible (defense in depth). Nothing in WHP needs HTTP/2 or mod_md inside a container: the HAProxy edge terminates h2/h3 and speaks HTTP/1.1 to backends, and Let's Encrypt is done by the edge. (Also fixes the CVE-2026-106023 mod_md crash surface: mod_md is not installed on EL10 at all.)Changes
scripts/httpd-h2-md-gate.sh(new):removeuninstalls themod_http2/mod_mdRPMs if present (mod_http2is a separate package, nothing requires it;dnf remove --assumenoshowed it removes only that 1 package and keeps httpd).checkfails the build ifrpm -q mod_http2|mod_mdsucceeds,httpd -Mlistshttp2_module/proxy_http2_module/md_module(anchored, sosystemd_moduledoes not match), orhttpd -tfails; writes/etc/whp-httpd-version.Dockerfile(cac php82-85, also form-sender base),Dockerfile.shared-httpd,Dockerfile.fpm: finalRUN gate remove && gate check(after all package steps) andLABEL org.whp.httpd-h2-md="removed". cac-fpm only has httpd-core (no mod_http2) so it is gate-only./etc/httpd/conf.modules.d/10-h2.conf,10-proxy_h2.conf,mod_http2.so,mod_proxy_http2.so..gitea/workflows/build-push.yaml: gate script added to the shellcheck list.docker run --rm --entrypoint cat IMG /etc/whp-httpd-version(a LABEL cannot hold a value computed in a RUN; the static label marks hardened images).Protocols/MDomain/h2://reference exists in this repo's configs/scripts; none in the WHP repo's Apache templates (only the Go panel's own HTTP/2 server and docs).Verified locally (amd64; arm64 build of shared-httpd also passes, gate OK under qemu)
cac php85, shared-httpd, cac-fpm php83 built; gate OK in each;
httpd -Mhas none of the 3 modules,httpd -tSyntax OK; HTTP/1.1 requests served (cac: 200 over https/1.1 with--http2negotiating 1.1); h2c prior-knowledge fails; shared-httpd listens :80/:443 and behaves identically to the current image. Negative test: gate run against the current publishedcac:php83exits 1.NOT verified: the real CI run, the pkg-cache path,
cac-litespeed/OLS images (not Apache, untouched).IMPORTANT: merging triggers a full rebuild
build-push.yamlruns on push totrunkand publishes the whole matrix (cac, cac-fpm, litespeed, shared-httpd, ...). That is intended (all images refreshed). Pushing this branch does not publish anything.Before merging, record rollback digests for every tag:
After merge verify: every Build job green; on a canary pull,
httpd -M | grep -E '^ (http2|proxy_http2|md)_module'empty,cat /etc/whp-httpd-version, sites load (test server first), then roll fleet. Rollback = retag the recorded digest. Rebuild again when Alma ships httpd 2.4.71 (module removal can stay).🤖 Generated with Claude Code
https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb