CVE-2026-44974 - @hapi/content parameter smuggling upload-filter bypass

@hapi/content before 6.0.2 parsed duplicate header parameters inconsistently. Content.disposition() kept the last occurrence of a parameter, while Content.type() kept the first occurrence for selected parameters such as charset and boundary. That mismatch can become a parameter-smuggling primitive when an upload filter, WAF, reverse proxy, middleware, or downstream storage path resolves duplicate parameters differently.

The most important production shape is upload filtering. If one component allows a request because it sees a safe filename or media boundary, while the component that writes or executes the upload sees the attacker-controlled duplicate, filename allowlists and content-type controls can be bypassed.

When to use it

Use this recipe when a Node.js repository, upload service, API gateway, or storage pipeline depends on @hapi/content or parses multipart/header parameters at a trust boundary. It supports source-code remediation, upload filter bypass review, parser-consistency audit, and evidence that duplicate Content-Disposition or Content-Type parameters cannot smuggle unsafe filenames or metadata past controls.

Inputs

  • @hapi/content version, package lockfiles, upload routes, reverse proxies, WAF rules, storage key generation, and filename/content-type filters.
  • Source paths that parse Content-Disposition, Content-Type, multipart boundaries, filenames, charsets, or downstream storage metadata.
  • Regression fixtures for duplicate parameters, mixed casing, quoted values, encoded filenames, benign uploads, and expected reject behavior.
  • Boundary evidence showing every parser in the path sees the same filename, content type, boundary, and storage destination.

Affected versions

Package Vulnerable versions Fixed versions
@hapi/content < 6.0.2 6.0.2+

Indicator-of-exposure

  • The repository resolves @hapi/content <6.0.2 directly or through Hapi upload, multipart, content negotiation, reverse-proxy, API gateway, or custom header parsing code.
  • Upload controls rely on Content-Disposition parameters such as filename, name, or filename* to enforce extension allowlists, storage paths, scan routing, tenant ownership, or executable-file denial.
  • Content routing, deserialization, parser choice, or sanitizer selection relies on Content-Type parameters such as charset or boundary.
  • Multiple components parse the same header: WAF, proxy, framework middleware, @hapi/content, multipart parser, object storage metadata, antivirus scanner, image processor, or downstream worker.
  • The application accepts direct-to-app uploads from untrusted users or imports uploads from email, webhooks, federation, partner APIs, support portals, CMS features, or agent/tool attachments.

Quick checks:

rg -n "@hapi/content|Content\\.disposition|Content\\.type|content-disposition|Content-Disposition|Content-Type|filename\\*?|boundary|multipart|form-data|multer|busboy|formidable|hapi|uploads?|allowlist|denylist" .
npm ls @hapi/content
pnpm why @hapi/content
yarn why @hapi/content
bun pm ls @hapi/content

Windows:

rg -n '@hapi/content|Content\.disposition|Content\.type|content-disposition|Content-Disposition|Content-Type|filename\*?|boundary|multipart|form-data|multer|busboy|formidable|hapi|uploads?|allowlist|denylist' .
npm ls @hapi/content
pnpm why @hapi/content
yarn why @hapi/content
bun pm ls @hapi/content

Do not upload executable test files to live services or send malformed headers through production WAFs during triage.

Remediation strategy

  • Upgrade every controlled @hapi/content dependency, lockfile, workspace, generated dependency report, SBOM, Docker layer, CI image, and devcontainer to 6.0.2+.
  • Add or verify request-boundary validation that rejects duplicate parameters in Content-Disposition and Content-Type before upload allowlists, storage-path decisions, parser selection, or worker routing consume them.
  • Normalize parser ownership. The same component should make the security decision and pass a canonicalized representation downstream, rather than letting a WAF, middleware, and worker each reinterpret raw header parameters.
  • For upload filters, key decisions from server-generated metadata after parsing and validation. Do not trust client filenames for storage paths, executable-file denial, tenant routing, or scanner bypass decisions.
  • Add regression tests for duplicate filename, filename*, charset, and boundary parameters that prove ambiguous requests are rejected, not silently accepted with first-wins or last-wins behavior.
  • If upgrade is blocked, contain by rejecting duplicate header parameters at the edge and disabling upload features where duplicate handling cannot be made unambiguous.

The prompt

Model context: this prompt was generated by GPT 5.5 Extra High reasoning.

You are remediating CVE-2026-44974 / GHSA-36hh-x5p5-jgc8, a high-severity
`@hapi/content` parameter-smuggling issue where duplicate `Content-Disposition`
or `Content-Type` parameters can be interpreted inconsistently and bypass
upload filters. Produce exactly one output:

- A reviewer-ready PR/change request that upgrades `@hapi/content`, refreshes
  generated artifacts, rejects duplicate security-relevant header parameters at
  upload and content-routing trust boundaries, adds safe regression tests, and
  documents operator validation, or
- `TRIAGE.md` if this repository does not control an affected dependency,
  upload parser, header parser, image/container, or deployable request path.

## Rules

- Scope only CVE-2026-44974 / GHSA-36hh-x5p5-jgc8 and directly related Hapi,
  upload, multipart, header parsing, content-routing, WAF/proxy, and generated
  dependency artifacts.
- Treat uploaded files, tenant IDs, filenames, object storage keys, scanner
  output, customer content, support attachments, webhook payloads, and request
  logs as sensitive.
- Do not upload executable files to live services, bypass production WAFs,
  probe tenant uploads, print customer filenames, or run malformed-header tests
  against production systems.
- Do not remove upload validation, antivirus scanning, content-type checks,
  tenant isolation, or audit logging to make the advisory appear fixed.
- Do not auto-merge.

## Steps

1. Inventory every controlled `@hapi/content` consumer: package manifests,
   lockfiles, workspaces, Hapi plugins, upload handlers, multipart parsers,
   reverse-proxy adapters, API gateways, Dockerfiles, devcontainers, generated
   dependency reports, SBOMs, and CI images.
2. Determine every resolved `@hapi/content` version. A target is vulnerable if
   it resolves to `<6.0.2`.
3. Search for request paths that parse or trust `Content-Disposition` or
   `Content-Type` parameters, especially `filename`, `filename*`, `name`,
   `charset`, and `boundary`.
4. Map each upload or content-routing decision that depends on those
   parameters: extension allowlists, executable-file denial, object storage
   paths, tenant routing, scanner selection, image/document processing,
   deserialization, webhook import, email attachment import, and agent/tool
   attachment handling.
5. If the repository does not resolve an affected package and does not own a
   relevant header-parsing or upload path, stop with `TRIAGE.md` listing
   checked files, resolved versions, and any external platform owner.
6. Upgrade `@hapi/content` to `6.0.2+`. Keep Hapi framework packages,
   multipart parsers, lockfiles, SBOMs, generated dependency reports, CI
   images, and container layers consistent with the patched dependency graph.
7. Add or verify duplicate-parameter rejection before security decisions:
   - reject duplicate `Content-Disposition` parameters;
   - reject duplicate `Content-Type` parameters used for parser or sanitizer
     selection;
   - handle case-insensitive parameter names consistently;
   - reject ambiguous encoded parameter names where framework APIs expose raw
     headers;
   - log only safe request metadata without customer filenames or file content.
8. Align parser ownership so the component that validates the header also
   supplies canonical metadata to downstream workers. Avoid designs where a WAF
   allows one interpretation and the application stores another.
9. Add safe regression tests using inert sample headers and temporary files:
   - duplicate `filename` values are rejected;
   - duplicate `filename*` and mixed `filename`/`filename*` policy is explicit;
   - duplicate `charset` and `boundary` values are rejected when they influence
     parser choice;
   - upload allowlists do not depend on raw client filenames;
   - logs and test output do not include customer content or secrets.
10. Add a PR body section named `CVE-2026-44974 operator actions` that states:
    - `@hapi/content` versions before and after;
    - which upload or header parsing paths were checked;
    - which duplicate-parameter guards or tests were added;
    - whether any WAF/proxy/parser disagreement remains and who owns it;
    - whether caches, generated artifacts, images, or SBOMs were refreshed;
    - which validation commands passed.
11. Run available validation: package install, lockfile integrity, upload
    handler tests, header parser tests, lint/typecheck, unit tests, build,
    dependency/security scans, SBOM refresh, image build, and CI workflow
    validation.
12. Use PR title:
    `fix(sec): remediate CVE-2026-44974 in @hapi/content uploads`.

## Stop conditions

- No affected `@hapi/content` package, upload parser, header parser, image, or
  deployable request path is controlled by this repository.
- The affected runtime is supplied only by an external platform or reverse
  proxy; document the owner, required fixed version, containment, and due date.
- Upload-parser changes require product ownership outside this PR; document the
  owner, blast radius, temporary duplicate-parameter rejection, and follow-up.
- Verification would require sending malformed headers to production, probing
  tenant uploads, uploading executable files, or exposing customer content.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Output contract

  • A reviewer-ready PR or change request that upgrades @hapi/content, rejects duplicate parameters at upload trust boundaries, aligns parser behavior, adds regression tests, and documents rollout controls.
  • Or a TRIAGE.md file that lists inspected files, owner, observed version, upload boundary, parser mismatch, required fix, and residual risk.
  • The output must include exact validation commands and must not upload real customer files, bypass production filters, or expose storage credentials.

Verification - what the reviewer looks for

  • No controlled package manifest, lockfile, SBOM, generated dependency report, Docker layer, CI image, or devcontainer resolves @hapi/content <6.0.2.
  • Upload and content-routing security decisions reject duplicate relevant header parameters instead of relying on first-wins or last-wins behavior.
  • Tests cover duplicate filename, filename*, charset, and boundary cases without live uploads or sensitive fixtures.
  • WAF, proxy, framework, parser, and downstream worker behavior are aligned or documented with an owner and containment.
  • PR notes name refreshed artifacts and validation commands.

Watch for

  • Updating only direct dependencies while Hapi plugins, framework packages, generated SBOMs, or container layers still resolve an older transitive copy.
  • Upload extension allowlists that inspect one parsed filename while storage or processing code uses another.
  • Case-sensitive duplicate checks that miss Filename versus filename.
  • Allowing both filename and filename* without an explicit conflict policy.
  • Treating this as a library-only bump while WAF, proxy, middleware, and worker parsers still disagree about duplicate header parameters.
  • Regression tests that assert normal uploads still work but never cover ambiguous duplicate-parameter rejection.

References