dotnet / dotnet/aspnetcore

Cache-key collision in Microsoft.AspNetCore.OutputCaching

Open
#68,912 1 comment 0 reactions 0 assignees View on GitHub
area-middleware feature-output-caching
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.