Skip to content

Fix: reject '@' in HTTP header field names per RFC 9110#12838

Open
prabhleen0601-stack wants to merge 1 commit intoapache:masterfrom
prabhleen0601-stack:fix-header-at-symbol
Open

Fix: reject '@' in HTTP header field names per RFC 9110#12838
prabhleen0601-stack wants to merge 1 commit intoapache:masterfrom
prabhleen0601-stack:fix-header-at-symbol

Conversation

@prabhleen0601-stack
Copy link

RFC 9110 defines HTTP header field names as tokens, which must not contain '@'.

Currently '@' is accepted because of MIME separator handling.

This patch ensures ParseRules::is_http_field_name rejects '@', aligning behavior with RFC 9110.

This prevents invalid header names from being accepted.

RFC 9110 defines HTTP header field names as tokens, which must not contain '@'.

Currently '@' is accepted because of MIME separator handling.

This patch ensures ParseRules::is_http_field_name rejects '@', aligning behavior with RFC 9110.

This prevents invalid header names from being accepted.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes HTTP header field name validation to comply with RFC 9110 by rejecting the '@' character. The current implementation incorrectly accepts '@' due to MIME separator handling logic.

Changes:

  • Removed the exception that allowed '@' in HTTP header field names
  • Updated the validation logic to properly reject all MIME separators including '@'

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

{
#ifndef COMPILE_PARSE_RULES
return (parseRulesCType[static_cast<unsigned char>(c)] & is_token_BIT);
return (parseRulesCType[(unsigned char)c] & is_token_BIT);
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

Changed from static_cast<unsigned char> to C-style cast (unsigned char). C++ best practice is to use static_cast for type safety and clarity. This change appears unrelated to the PR's stated purpose of fixing '@' validation.

Suggested change
return (parseRulesCType[(unsigned char)c] & is_token_BIT);
return (parseRulesCType[static_cast<unsigned char>(c)] & is_token_BIT);

Copilot uses AI. Check for mistakes.
{
#ifndef COMPILE_PARSE_RULES
return (parseRulesCType[static_cast<unsigned char>(c)] & is_token_BIT);
return (parseRulesCType[(unsigned char)c] & is_token_BIT);
Copy link
Contributor

Choose a reason for hiding this comment

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

no C casts, please

@bneradt
Copy link
Contributor

bneradt commented Feb 4, 2026

Looks like some of the catch tests failed:
https://ci.trafficserver.apache.org/job/Github_Builds/job/fedora/7450/

The following tests FAILED:
	 28 - test_proxy_hdrs (Failed)

Copy link
Contributor

@bneradt bneradt left a comment

Choose a reason for hiding this comment

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

Thanks for looking into RFC compliance. However, this change breaks the unit tests because ATS intentionally allows @ in header field names for internal headers.

Why the test fails

The test at src/proxy/hdrs/unit_tests/test_Hdrs.cc:583 expects @ to be valid:

{"delimiter_@: 0\r\n",         ParseResult::CONT }, // Not allowed by the spec, but we use it as internal header indicator

The comment explicitly acknowledges this is a deliberate deviation from the spec.

Internal header usage

ATS uses @ as a prefix convention for internal headers:

  1. @Ats-Internal is defined as a well-known header token in src/proxy/hdrs/HdrToken.cc:90
  2. MIME_FIELD_ATS_INTERNAL references this in src/proxy/hdrs/MIME.cc:716
  3. The aws_auth_v4 plugin explicitly skips headers starting with @ because they're internal (plugins/origin_server_auth/aws_auth_v4.cc:434-435):
    /* Skip internal headers (starting with '@'*/
    if ('@' == name[0] /* exclude internal headers */) {
  4. The ESI plugin tests use @-prefixed headers for internal testing

Recommendation

The original exception (is_mime_sep(c) && c != '@') was intentional. If strict RFC 9110 compliance is desired, this would require a broader refactoring effort to:

  1. Replace @Ats-Internal with an alternative internal header mechanism
  2. Update all plugins that rely on the @ prefix convention
  3. Update the unit test expectations

As it stands, simply removing the @ exception will break internal functionality.

Is there a specific issue you are trying to address with this patch? Maybe we can address it in a different way.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants