dotnet-api-docs icon indicating copy to clipboard operation
dotnet-api-docs copied to clipboard

Document TryAddWithoutValidation security implications and validation behavior

Open Copilot opened this issue 1 month ago • 2 comments

TryAddWithoutValidation methods perform header name validation but skip header value validation, creating security risks when used with untrusted input. This was undocumented.

Changes

  • Clarified validation behavior: Header names are validated (returns false for invalid names), but header values are not
  • Added security warning: Values must be trusted or validated to prevent protocol-level attacks
  • Provided minimum validation guidance: Prohibit newline characters (\r, \n, \0) to prevent request smuggling:
    if (value.IndexOfAny(new[] { '\r', '\n', '\0' }) >= 0) throw ...
    
  • Documented observable behavior: Unvalidated values appear in enumeration and queries, even without using NonValidated view

Both TryAddWithoutValidation overloads now have identical, comprehensive remarks sections explaining these behaviors.

Original prompt

Improve the TryAddWithoutValidation docs.

Here are the relevant sections from internal documentation:

TryAddWithoutValidation methods do perform header name validation, returning false for invalid names.

TryAddWithoutValidation methods do not perform any header value validation. Values added via these methods are assumed to be trusted, and other application logic, such as HttpClient, may misbehave if they are not well formed. In particular, callers are highly encouraged to validate that these values not contain new line characters to guard against attacks such as request smuggling.
Values added without validation may be observed when enumerating the collection or querying for the specific header name, even when the caller is not using the HttpHeaders.NonValidated view of the collection.

TryAddWithoutValidation must never be used with untrusted values, unless it was otherwise sufficiently validated.
What constitutes "sufficient" validation can vary by use case. At a minimum, prohibit new line characters for protocol correctness, e.g. if (value.ContainsAny('\r', '\n', '\0')) throw .... This should ensure that the server application sees values in the same way as the client application, with the server now being responsible for properly sanitizing its own inputs.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot avatar Jan 13 '26 15:01 Copilot