Skip to content

fix uhv underscore header sanitization use-after-free path#44086

Open
Achieve3318 wants to merge 1 commit intoenvoyproxy:mainfrom
Achieve3318:fix-44032-uhv-underscore-uaf
Open

fix uhv underscore header sanitization use-after-free path#44086
Achieve3318 wants to merge 1 commit intoenvoyproxy:mainfrom
Achieve3318:fix-44032-uhv-underscore-uaf

Conversation

@Achieve3318
Copy link

Summary

This PR fixes a potential use-after-free path in underscore-header sanitization for Envoy default UHV when headers_with_underscores_action is DROP_HEADER.

In sanitizeHeadersWithUnderscores(), header names were collected as non-owning absl::string_view values and then removed from the same header map. With duplicate underscore headers (for example, x_foo appearing multiple times), removing one header can invalidate storage referenced by later views.

This change stores owning copies of header names (std::string) before mutation, preventing reads from dangling references during removal.

Fixes: #44032

Changes

  • Updated:
    • source/extensions/http/header_validators/envoy_default/header_validator.cc
  • Replaced:
    • std::vector<absl::string_view> with std::vector<std::string>
    • push_back(header_name) with emplace_back(header_name)
  • Added regression tests for duplicate underscore headers:
    • test/extensions/http/header_validators/envoy_default/http1_header_validator_test.cc
    • test/extensions/http/header_validators/envoy_default/http2_header_validator_test.cc

Test Plan

  • Ran:
    • //test/extensions/http/header_validators/envoy_default:http1_header_validator_test
    • //test/extensions/http/header_validators/envoy_default:http2_header_validator_test
  • Both passed locally.

@repokitteh-read-only
Copy link

Hi @Achieve3318, welcome and thank you for your contribution.

We will try to review your Pull Request as quickly as possible.

In the meantime, please take a look at the contribution guidelines if you have not done so already.

🐱

Caused by: #44086 was opened by Achieve3318.

see: more, trace.

Use owning header-name copies when collecting underscore headers to drop,
so duplicate header removals cannot read dangling views. Add HTTP/1 and
HTTP/2 regression coverage for duplicate underscore header names.

Signed-off-by: Achieve3318 <daniel98518@gmail.com>
@Achieve3318 Achieve3318 force-pushed the fix-44032-uhv-underscore-uaf branch from c30712d to a5a0ba6 Compare March 23, 2026 12:48
@Achieve3318 Achieve3318 requested a deployment to external-contributors March 23, 2026 12:48 — with GitHub Actions Waiting
@Achieve3318
Copy link
Author

hi, @paul-r-gall Please review my PR

Comment on lines +637 to +644
// Store owning copies because removing one duplicate header can free the
// underlying storage for another matching entry.
std::vector<std::string> drop_headers;
header_map.iterate([&drop_headers](const ::Envoy::Http::HeaderEntry& header_entry)
-> ::Envoy::Http::HeaderMap::Iterate {
const absl::string_view header_name = header_entry.key().getStringView();
if (absl::StrContains(header_name, '_')) {
drop_headers.push_back(header_name);
drop_headers.emplace_back(header_name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than keep a copy, could we keep header name in a absl::flat_hash_set?

@wbpcode wbpcode assigned yanavlasov and wbpcode and unassigned yanavlasov Mar 25, 2026
@wbpcode
Copy link
Member

wbpcode commented Mar 25, 2026

/wait

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

uhv: use-after-free read in sanitizeHeadersWithUnderscores with duplicate underscore headers

3 participants