Skip to content

Cookie encoding issue in ODataBatchReaderExtensions.cs #2894

@finalfree

Description

@finalfree

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);
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions