Skip to content

Prevent corrupted SMTP headers when MailAddress.DisplayName contains CR/LF#128980

Open
MihaZupan with Copilot wants to merge 6 commits into
mainfrom
copilot/fix-corrupted-email-headers
Open

Prevent corrupted SMTP headers when MailAddress.DisplayName contains CR/LF#128980
MihaZupan with Copilot wants to merge 6 commits into
mainfrom
copilot/fix-corrupted-email-headers

Conversation

Copilot AI commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

MailAddress accepted display names containing \r/\n and SmtpClient embedded them verbatim into From:/To: headers, breaking header structure and SMTP framing. Typical source: a trailing newline left over from parsing upstream input.

Changes in MailAddress.TryParse (src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs):

  • Caller-supplied display name: reject CR/LF by throwing FormatException, matching the existing convention for MailMessage.Subject (MailBnfHelper.HasCROrLFMailSubjectInvalidFormat). TryCreate returns false.
  • Display name parsed out of the address string: unfold per RFC 5322 §3.2.4 by stripping CR/LF from the stored value. This preserves the previously-accepted folded input "display \r\n name" <"folding"@domain.com> while ensuring re-encoding produces a clean header.
  • New StripCRLF helper (guarded by an HasCROrLF pre-check, so allocation only occurs when needed).
// Now throws FormatException instead of producing a broken From: header
new MailAddress("user@example.com", "Display Name\r\n");

Test coverage added in MailAddressDisplayNameTest.MailAddress_Ctor_DisplayNameContainsCRLF_Throws for CR, LF, and CRLF in leading/middle/trailing positions and inside bounding quotes, against both the constructor and TryCreate.

Copilot AI requested review from Copilot and removed request for Copilot June 4, 2026 11:51
Copilot AI linked an issue Jun 4, 2026 that may be closed by this pull request
@MihaZupan MihaZupan assigned mrek-msft and unassigned MihaZupan Jun 4, 2026
…TP headers

Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot June 4, 2026 12:21
Copilot AI changed the title [WIP] Fix corrupted email headers due to new line in DisplayName Prevent corrupted SMTP headers when MailAddress.DisplayName contains CR/LF Jun 4, 2026
Copilot AI requested a review from MihaZupan June 4, 2026 12:22
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @karelz, @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Comment thread src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs Outdated
…edDisplayName flag

Co-authored-by: mrek-msft <188900745+mrek-msft@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 7, 2026 09:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 hardens System.Net.Mail against CR/LF injection/corruption via MailAddress.DisplayName, preventing malformed From:/To: header output when addresses are serialized for SMTP.

Changes:

  • Add CR/LF rejection for caller-supplied displayName in MailAddress.TryParse (throwing for constructors; TryCreate returns false).
  • Strip CR/LF from display names parsed out of the full address string (unfolding) via a new StripCRLF helper.
  • Add unit tests covering CR, LF, and CRLF in caller-supplied display names for both MailAddress constructors and TryCreate.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs Reject CR/LF in caller-supplied display names; strip CR/LF from parsed display names to avoid header corruption.
src/libraries/System.Net.Mail/tests/Unit/MailAddressTests/MailAddressDisplayNameTest.cs Add unit tests asserting CR/LF in caller-supplied display names throws / fails TryCreate.

Comment on lines +171 to +180
@@ -158,13 +172,34 @@ private static bool TryParse([NotNullWhen(true)] string? address, string? displa
if (string.IsNullOrEmpty(displayName))
{
displayName = info.DisplayName;

// The display name parsed out of 'address' may contain folding white space
// (CRLF inside a quoted string, RFC 5322 §3.2.4). Unfold by stripping any
// CR/LF characters so re-encoding into a header does not corrupt the output.
if (!string.IsNullOrEmpty(displayName) && MailBnfHelper.HasCROrLF(displayName))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot consider fixing on other places or reusing logic. Please take in account recently merged fix #130175.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in f12da96. The branch now aligns with #130175 by rejecting CR/LF at the parser level for address strings (covering ParseMultipleAddresses/MailAddressCollection.Add and MailMessage construction), while keeping the separate rejection for caller-supplied displayName. I also removed the earlier unfold path and updated the affected unit/functional tests accordingly.

Comment on lines +65 to 80
[Theory]
[InlineData("Display\rName")]
[InlineData("Display\nName")]
[InlineData("Display\r\nName")]
[InlineData("DisplayName\r")]
[InlineData("DisplayName\n")]
[InlineData("DisplayName\r\n")]
[InlineData("\rDisplayName")]
[InlineData("\nDisplayName")]
[InlineData("\"Display\r\nName\"")]
public void MailAddress_Ctor_DisplayNameContainsCRLF_Throws(string displayName)
{
Assert.Throws<FormatException>(() => new MailAddress(Address, displayName));
Assert.False(MailAddress.TryCreate(Address, displayName, out _));
}
}
Copilot AI and others added 2 commits July 7, 2026 15:22
Co-authored-by: mrek-msft <188900745+mrek-msft@users.noreply.github.com>
Co-authored-by: mrek-msft <188900745+mrek-msft@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 7, 2026 15:23
Co-authored-by: mrek-msft <188900745+mrek-msft@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 7, 2026 15:24
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.

Corrupted email headers when DisplayName contains new line

4 participants