Skip to content

Fix response cookie duplication in ASP.NET Core integration#3361

Open
MO2k4 wants to merge 3 commits intoAzure:mainfrom
MO2k4:feature/issue-3353-cookie-duplication
Open

Fix response cookie duplication in ASP.NET Core integration#3361
MO2k4 wants to merge 3 commits intoAzure:mainfrom
MO2k4:feature/issue-3353-cookie-duplication

Conversation

@MO2k4
Copy link
Copy Markdown
Contributor

@MO2k4 MO2k4 commented Apr 10, 2026

Summary

Fixes #3353 — calling response.Cookies.Append() multiple times duplicates all previous Set-Cookie header values exponentially.

  • Root cause: The IHeaderDictionary indexer setters in AspNetCoreHttpHeadersCollection used TryAddWithoutValidation() which appends values to an existing key. The contract requires replace semantics. When ASP.NET Core's internal ResponseCookies.Append() reads all existing Set-Cookie values, appends the new cookie, and sets the combined result back via the indexer, the old values are preserved AND the combined values are added — causing exponential duplication.
  • Fix: Call Remove(key) before TryAddWithoutValidation(key, value) in both indexer setters (explicit IHeaderDictionary and public).
  • Change surface: 2 lines of production code in AspNetCoreHttpHeadersCollection.cs.

Note for reviewers

The Add(string key, StringValues value) method (line 157) in the same class also uses TryAddWithoutValidation without removing first. This means IHeaderDictionary.Add has append behavior rather than throwing on duplicate keys. This is not the cause of the cookie bug (ASP.NET Core uses the indexer, not Add, for cookie header manipulation), but it may warrant a follow-up to align with standard IDictionary.Add semantics.

Test plan

  • IndexerSetter_ShouldReplaceValues_NotAppend — sets a header twice via the indexer, asserts only the second value remains
  • CookiesAppend_ShouldNotDuplicateSetCookieHeaders — reproduces exact issue: 1 manual Set-Cookie header + 3 Cookies.Append calls = 4 values (was 15 before fix)
  • MultipleCookiesAppend_ShouldNotDuplicate — 3 Cookies.Append calls = 3 values
  • All 26 existing Worker.Extensions.Http.AspNetCore.Tests pass
  • All 295 DotNetWorker.Tests pass

The IHeaderDictionary indexer setters in AspNetCoreHttpHeadersCollection
used TryAddWithoutValidation which appends values instead of replacing
them. When ASP.NET Core's ResponseCookies.Append reads existing
Set-Cookie values and writes them back with the new cookie, the append
behavior caused exponential duplication.

Fix: call Remove(key) before TryAddWithoutValidation in both indexer
setters to give correct replace semantics.
@jviau
Copy link
Copy Markdown
Contributor

jviau commented Apr 16, 2026

/azp run dotnet-worker.public

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Match ASP.NET Core's HeaderDictionary contract: assigning StringValues.Empty
via the indexer should remove the header rather than store an empty entry.
Addresses PR review feedback on Azure#3361.
@jviau
Copy link
Copy Markdown
Contributor

jviau commented Apr 16, 2026

/azp run dotnet-worker.public

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@jviau
Copy link
Copy Markdown
Contributor

jviau commented Apr 16, 2026

@MO2k4 can you update the release notes https://github.com/Azure/azure-functions-dotnet-worker/blob/main/extensions/Worker.Extensions.Http.AspNetCore/release_notes.md to reflect this change? Remove the existing entry there, that has already shipped.

@MO2k4
Copy link
Copy Markdown
Contributor Author

MO2k4 commented Apr 16, 2026

@jviau release notes are added and i removed the old entry

@jviau
Copy link
Copy Markdown
Contributor

jviau commented Apr 16, 2026

/azp run dotnet-worker.public

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Response cookies are duplicated

2 participants