dotnet / dotnet/aspnetcore

[Validation] The TempData cookie

Open
#69,137 1 comment 0 reactions 1 assignee Claimed by @PreethikaSelvam View on GitHub
area-blazor Validation validation-scenario
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.