[Validation] The TempData cookie
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 276
Description
**Scenario contact:** @dariatiurina
## Scenario
By default TempData travels in an encrypted, `HttpOnly` cookie, so nothing has to be registered and nothing is kept on the server. That makes the cookie's own properties part of the feature: it is protected with the app's data protection keys, it is chunked when it grows past what one cookie holds, and its path follows the app's path base. A cookie that cannot be decrypted has to degrade to no value rather than an error page.
Validate the cookie's attributes and size handling, and that tampering or a data protection key the app cannot read produces an empty value and a clean recovery.
## Minimum build
.NET 11 RC1.
## Configurations to cover
* Blazor Web App
* [x] Static SSR
* [ ] Interactive Server
* [ ] Interactive WebAssembly
* [ ] Interactive Auto
* [ ] Standalone WebAssembly
* [ ] Hybrid (MAUI)
## Also exercise
* [ ] Published output
* [ ] An existing .NET 10 app upgraded to .NET 11
* [ ] Trimming or ahead-of-time compilation
* [ ] More than one server instance, or a proxy in front
* [ ] Hot Reload
* [ ] An IDE as well as the command line
* [ ] Container
* [x] N/A
## Setup
Use an isolated test app and synthetic values. For the unreadable-key comparison, use dedicated test key directories and distinct Data Protection application identities. Do not delete or modify a shared development or production key ring. Normal key rotation retains older keys for decryption, and deleting files does not reliably remove keys already cached by a running process.
## What to build
A page that writes a message to TempData and redirects to an ordinary consuming reader, as small as possible: the point here is the cookie rather than the flow.
Add a control that writes a value of a chosen size. Use a modest payload that spans two or three chunks, staying below the browser's total-cookie and server's request-header limits. Record encoded size and chunk count rather than expecting arbitrary payload sizes to work.
Configure a custom cookie name for one run, and host the app under a path base for another.
## Things to try
* Write a value and inspect the resulting cookie in devtools: its name, size, and every attribute.
* Try to read the cookie from `document.cookie` in the browser console.
* Search the cookie value for the message text you stored.
* Grow the payload enough to require multiple cookie chunks, then confirm the value comes back intact within the configured browser and server limits.
* Replace the test cookie with one representative unreadable value and observe recovery. Repeatedly inventing new corruptions is not needed.
* In a separate run, present a cookie to the isolated test app using incompatible test keys or a different application identity. Compare it with the unreadable-cookie case. A valid cookie from another run with matching keys and identity is not a corruption case.
* Host the app under a path base and look at the cookie's `Path`.
* Set a custom cookie name and confirm it is used.
* After a failed read, check whether the next request is clean.
## Expected behavior
The cookie carries the value opaquely and is not reachable from script. A cookie that cannot be decrypted yields no value, is removed, and does not produce an error page.
### Must hold
* The cookie is `HttpOnly` and is not returned by `document.cookie`.
* The stored message does not appear in readable form anywhere in the cookie value.
* The bounded multi-chunk payload comes back equal to what was written, without exceeding browser cookie quotas or server header limits.
* With a tampered cookie the page returns HTTP 200 with no message, and the response carries a `Set-Cookie` that removes the bad cookie, so the following request is clean.
* When the app is hosted under a path base, the cookie's `Path` matches that path base.
* A custom cookie name is used for both writing and reading.
### Expected differences between configurations
* An unreadable cookie and one protected with incompatible keys or application identity both exercise load-failure recovery. Ordinary key rotation does not imply that older cookies become unreadable.
## Evidence to capture
* The `Set-Cookie` header after the write and the `Cookie` header on the following request, with the protected value redacted but every attribute kept.
* The cookie's name and encoded size for the small and multi-chunk payloads, the number of chunks, and the browser/server limits used.
* The full response to the tampered-cookie request, showing the status code and the removal `Set-Cookie`.
## Documentation to use
* [ASP.NET Core Blazor state management](https://learn.microsoft.com/en-us/aspnet/core/blazor/state-management/server?view=aspnetcore-11.0#temporary-data-persistence)
Report whether the docs mention the cookie's size limit and what happens when it cannot be decrypted. Both matter to anyone deploying more than one instance.
## What to report
Report results using the format described in the [validation testing manual](https://github.com/dotnet/aspnetcore/issues/68479). Include link to a repository with the test app.
Contributor guide
Assessment
This issue has not been assessed yet.