Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 10, 2025

Fix JsonIgnore validation bypass for write-only conditions

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Validation attributes on properties with JsonIgnore write-only conditions were incorrectly skipped during model binding.

Description

The validation generator was treating all [JsonIgnore] attributes uniformly, skipping validation regardless of the Condition property. This caused properties with write-only conditions (e.g., WhenWritingDefault, WhenWritingNull) to bypass validation on inbound requests.

Changes:

  • Updated IsJsonIgnoredProperty to inspect JsonIgnore.Condition and only skip validation for conditions affecting deserialization (Always, WhenReading)
  • Properties with write-only conditions (Never, WhenWritingDefault, WhenWritingNull, WhenWriting) are now validated correctly
  • Added test coverage for all six JsonIgnoreCondition values

Example:

public class Model
{
    // Previously: validation skipped ❌  
    // Now: validation enforced ✅
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    [MaxLength(10)]
    public string? Property { get; set; }
}
Condition Affects Validation Behavior
Always Read & Write Skipped
WhenReading Read Skipped
Never, WhenWriting* Write only Now enforced
Original prompt

This section details on the original issue you should resolve

<issue_title>[JsonIgnore(WhenWritingDefault)] bypasses validation on inbound requests</issue_title>
<issue_description>### Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When a property is decorated with [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)], validation attributes (e.g., [MaxLength]) on that property are not enforced during model binding, even when the property value is present in the incoming request.

The JsonIgnoreCondition.WhenWritingDefault condition should only affect serialization (writing JSON output). It should not affect deserialization or validation of incoming requests.

Expected Behavior

A property with [MaxLength(10)] should be validated regardless of [JsonIgnore] attributes. The request should return 400 Bad Request when the value exceeds the maximum length.

Steps To Reproduce

Full repro: https://github.com/glenndierckx/aspnetcore-jsonignore-validation-bug

// Request model
public class ValidationTestRequest
{
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault), MaxLength(10)]
    public string? PropertyWithJsonIgnoreWhenWritingDefault { get; set; }

    [MaxLength(10)]
    public string? PropertyWithoutJsonIgnore { get; set; }
}

// Endpoint
app.MapPost("/test-validation", (ValidationTestRequest _) => Results.Ok());

Test Results:

Property JsonIgnore Attribute Value Sent Expected Actual
PropertyWithoutJsonIgnore None "ExceedsMaxLength" (14 chars) 400 Bad Request 400 Bad Request
PropertyWithJsonIgnoreWhenWritingDefault WhenWritingDefault "ExceedsMaxLength" (14 chars) 400 Bad Request 200 OK

Exceptions (if any)

No exception is thrown. The validation is silently bypassed and the endpoint handler is invoked with invalid data.

.NET Version

10.0.100

Anything else?

No response</issue_description>

<agent_instructions>Update https://github.com/dotnet/aspnetcore/blob/main/src/Validation/gen/Parsers/ValidationsGenerator.TypesParser.cs#L185 to only skip when the JsonIgnoreCondition is always or during reading.

Add test coverage for this.

JsonIgnoreCondition docs: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonignorecondition?view=net-10.0</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@captainsafia This happens because our [current check for the JsonIgnore attribute is unconditional](https://github.com/dotnet/aspnetcore/blob/main/src/Validation/gen/Parsers/ValidationsGenerator.TypesParser.cs#L185). We can resolve this by tightening up the check.

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits December 10, 2025 20:47
…ditions

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
…ability

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix validation bypass due to JsonIgnore when writing default Fix JsonIgnore validation bypass for write-only conditions Dec 10, 2025
Copilot AI requested a review from captainsafia December 10, 2025 20:55
@captainsafia captainsafia marked this pull request as ready for review December 10, 2025 22:41
Copilot AI review requested due to automatic review settings December 10, 2025 22:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a validation bypass vulnerability where properties decorated with [JsonIgnore] and write-only conditions (e.g., WhenWritingDefault, WhenWritingNull) were incorrectly skipping validation during model binding. The fix ensures that only conditions affecting deserialization (Always, WhenReading) skip validation, while write-only conditions and Never continue to be validated.

Key Changes:

  • Updated IsJsonIgnoredProperty method to inspect the JsonIgnore.Condition property and only skip validation for Always and WhenReading conditions
  • Added comprehensive test coverage for all six JsonIgnoreCondition enum values
  • Generated snapshot verification confirming correct validation behavior

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Validation/gen/Extensions/ITypeSymbolExtensions.cs Modified IsJsonIgnoredProperty to check JsonIgnore.Condition and only skip validation for Always (1) and WhenReading (5) conditions
src/Validation/test/Microsoft.Extensions.Validation.GeneratorTests/ValidationsGenerator.ComplexType.cs Added comprehensive test with 6 properties covering all JsonIgnoreCondition values and verifying correct validation behavior
src/Validation/test/Microsoft.Extensions.Validation.GeneratorTests/snapshots/ValidationsGeneratorTests.ValidatesPropertiesWithJsonIgnoreWhenWritingConditions#ValidatableInfoResolver.g.verified.cs Generated snapshot file showing only write-condition properties are included for validation

/// Checks if the property is marked with [JsonIgnore] attribute.
/// Checks if the property is marked with [JsonIgnore] attribute with a condition that affects deserialization.
/// Only skips validation when the condition is Always or WhenReading, as these affect the reading/deserialization process.
/// Properties with conditions that only affect writing (WhenWritingDefault, WhenWritingNull, WhenWriting) or Never are still validated.
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation mentions "WhenWriting" as a JsonIgnoreCondition value, but this does not exist in the System.Text.Json.Serialization.JsonIgnoreCondition enum. The actual enum values are: Never, Always, WhenWritingDefault, WhenWritingNull, and WhenReading. Remove the reference to "WhenWriting" from the documentation.

Suggested change
/// Properties with conditions that only affect writing (WhenWritingDefault, WhenWritingNull, WhenWriting) or Never are still validated.
/// Properties with conditions that only affect writing (WhenWritingDefault, WhenWritingNull) or Never are still validated.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[JsonIgnore(WhenWritingDefault)] bypasses validation on inbound requests

2 participants