Cache-key collision in Microsoft.AspNetCore.OutputCaching
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
When the default `OutputCacheOptions.UseCaseSensitivePaths = false` is in effect, `OutputCacheKeyProvider.TryAppendBaseKey` builds the base cache key by folding the request path one UTF-16 char at a time through `char.ToUpperInvariant` (`StringBuilderExtensions.AppendUpperInvariant`). Under the default ICU globalization mode this folds `U+017F LATIN SMALL LETTER LONG S (ſ)` to `S`, the same target ASCII `s` folds to, so two paths that ASP.NET Core routing and `StringComparer.OrdinalIgnoreCase` treat as distinct (`/foo/s/…` vs `/foo/ſ/…`) alias to a single OutputCache entry.
Hence the cache-key equivalence is broader than the application/routing path equivalence, allowing the response cached for one path to be served for a distinct path.
Also i.e. `U+212A KELVIN SIGN`.
Contributor guide
Research direction
Start at OutputCacheKeyProvider.TryAppendBaseKey and the StringBuilderExtensions.AppendUpperInvariant call described in the issue. Compare the cache-key folding behavior with ASP.NET Core routing and StringComparer.OrdinalIgnoreCase for the /foo/s/… and /foo/ſ/… paths, including U+212A, then add regression coverage showing distinct paths cannot share an OutputCache entry.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100