dotnet / dotnet/aspnetcore

[Razor] State pollution in `BeginWriteTagHelperAttribute` due to uncleared `_attributeInfo` in `RazorPageBase.EndWriteAttribute`

Open
#67,891 0 comments 0 reactions 0 assignees View on GitHub
area-mvc feature-tag-helpers
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

When an HTML dynamic attribute (e.g., `dir="@Model.Direction"`) is immediately followed by a TagHelper attribute that contains the `@@` escape sequence (e.g., ``), the internal `_attributeInfo` state in `RazorPageBase` is not properly cleared.

This causes a "dirty read" during the execution of the TagHelper attribute. Because the C# Razor compiler emits a `WriteAttributeValue` call inside `BeginWriteTagHelperAttribute()` when it splits the string at `@@`, it mistakenly inherits the stale `_attributeInfo` state and leaks the prefix of the previous HTML attribute (e.g., ` dir="`) directly into the middle of the TagHelper's generated output buffer.

### Expected Behavior

The previous attribute's state should be fully cleared when `EndWriteAttribute()` is called, preventing its prefix from polluting any subsequent TagHelper attributes. The TagHelper should correctly resolve the URL without injecting garbage text.

Expected Output:

```html

```

### Steps To Reproduce

1. Create a standard ASP.NET Core MVC or Razor Pages project.
2. Add the following markup to any `.cshtml` file (e.g., `_Layout.cshtml`). Notice that the `` tag has a dynamic attribute, followed immediately by a TagHelper attribute (`~/`) that contains an escaped `@` (`@@`):
```html

```
3. Run the application and inspect the page source.
4. The output will be silently corrupted with the `dir="` prefix leaking into the `href` attribute:
```html

```

### Exceptions (if any)

No exceptions are thrown. This is a silent HTML generation corruption bug.

### .NET Version

10.0 (Also reproducible in earlier .NET Core versions)

### Anything else?

**Root cause analysis:**
This occurs because `BeginWriteTagHelperAttribute` sets up a `StringWriter` buffer, and when the Razor Chunk Generator encounters the `@@` escape sequence, it breaks the string and emits a `WriteAttributeValue` call inside this scope.

Because `RazorPageBase.EndWriteAttribute` failed to reset the `_attributeInfo` struct, `WriteAttributeValue` sees `_attributeInfo.AttributeValuesCount == 1` and blindly prepends the stale prefix to the new buffer.

**Proposed Fix:**
A PR has already been prepared and submitted to fix this by adding `_attributeInfo = default;` to the end of `RazorPageBase.EndWriteAttribute()`. This guarantees the attribute scope state is properly cleared.

Contributor guide

Open the contributing guide

Research direction

Start at RazorPageBase.EndWriteAttribute and trace how _attributeInfo is read by BeginWriteTagHelperAttribute and WriteAttributeValue. Reproduce the provided .cshtml case in an ASP.NET Core MVC or Razor Pages project, then verify the generated link matches the expected output without the prior dir prefix.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, web-dev
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.