-
Notifications
You must be signed in to change notification settings - Fork 473
Open
Labels
Description
Exception
Invalid cookie value: 100,127.0.0.1,1,76a02e3b7c9b39b51bd1ef658e740b35,Edge,CN (Parameter 'value')
at Microsoft.Net.Http.Headers.CookieHeaderValue.CheckValueFormat(StringSegment value, String parameterName)
at Microsoft.Net.Http.Headers.CookieHeaderValue..ctor(StringSegment name, StringSegment value)
at Microsoft.AspNetCore.Http.Features.RequestCookiesFeature.set_Cookies(IRequestCookieCollection value)
at Microsoft.AspNet.OData.Batch.ODataBatchReaderExtensions.CreateHttpContext(HttpContext originalContext)
at Microsoft.AspNet.OData.Batch.ODataBatchReaderExtensions.ReadOperationInternalAsync(ODataBatchReader reader, HttpContext originalContext, Guid batchId, Nullable`1 changeSetId, CancellationToken cancellationToken, Boolean bufferContentStream)
Problem Description
I found that https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNetCore.OData/Batch/ODataBatchReaderExtensions.cs#L267 contains the following problematic code:
context.Request.Cookies = originalContext.Request.Cookies;If original cookie value contains url-encoded special characters, like a comma,
RequestCookieFeature.Cookies getter will return Urldecoded value.
https://github.com/dotnet/aspnetcore/blob/5b06d1d90f7d24dd0aa642e3f9ed2020646dfa96/src/Http/Shared/CookieHeaderParserShared.cs#L45
When we set the decoded cookie value to new context, RequestCookieFeature.Cookie will validate and throw exception.
https://github.com/dotnet/aspnetcore/blob/5b06d1d90f7d24dd0aa642e3f9ed2020646dfa96/src/Http/Headers/src/CookieHeaderValue.cs#L82
Steps to Reproduce
I write a unittest:
[Test]
public void CopyRequestCookies_WithEncodedIllegalValue_ThrowsArgumentException(string illegalCookieValue)
{
var encodedValue = Uri.EscapeDataString("100,127.0.0.1,1,76a02e3b7c9b39b51bd1ef658e740b35,Edge,CN");
var context = new DefaultHttpContext();
context.Request.Headers["Cookie"] = $"illegal={encodedValue}";
var original = context.Request.Cookies;
var ex = Assert.Throws<ArgumentException>(() =>
{
context.Request.Cookies = original;
});
Assert.That(ex!.Message, Does.Contain("Invalid cookie value").IgnoreCase);
}