Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CookieHeaderParserShared throws exception when last cookie contains invalid character #45014

Closed
1 task done
JmlSaul opened this issue Nov 11, 2022 · 11 comments · Fixed by #45127
Closed
1 task done

CookieHeaderParserShared throws exception when last cookie contains invalid character #45014

JmlSaul opened this issue Nov 11, 2022 · 11 comments · Fixed by #45127
Assignees
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions bug This issue describes a behavior which is not expected - a bug. good first issue Good for newcomers. help wanted Up for grabs. We would accept a PR to help resolve this issue
Milestone

Comments

@JmlSaul
Copy link

JmlSaul commented Nov 11, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Cookie String: keya=valuea; keyb=valueb; errorcookie=dd,:("sa;
the last part of cookie string above is an invalid cookie and the whole cookie string ends with ;,this will throw exception like below, and all cookies fails to be read.

Exception: Nullable object must have a value.

at Microsoft.Net.Http.Headers.CookieHeaderParserShared.TryParseValues(StringValues values, IDictionary`2 store, Boolean enableCookieNameEncoding, Boolean supportsMultipleValues)
at Microsoft.AspNetCore.Http.RequestCookieCollection.ParseInternal(StringValues values, Boolean enableCookieNameEncoding)
at Microsoft.AspNetCore.Http.Features.RequestCookiesFeature.get_Cookies()
... try get value from cookies

Cookie String: keya=valuea; keyb=valueb; errorcookie=dd,:("sa
the last part of this cookie string above is an invalid cookie and the whole cookie string ends without ;,this will not throw exception, the parser will ignore errorcookie

Expected Behavior

error cookie be ignored, and normal cookie still readable.

Steps To Reproduce

No response

Exceptions (if any)

Nullable object must have a value.

at Microsoft.Net.Http.Headers.CookieHeaderParserShared.TryParseValues(StringValues values, IDictionary`2 store, Boolean enableCookieNameEncoding, Boolean supportsMultipleValues)
at Microsoft.AspNetCore.Http.RequestCookieCollection.ParseInternal(StringValues values, Boolean enableCookieNameEncoding)
at Microsoft.AspNetCore.Http.Features.RequestCookiesFeature.get_Cookies()

.NET Version

7.0

Anything else?

visual studio 2022 17.4.0

@Tratcher
Copy link
Member

It's probably coming from this line:

store[parsedName.Value.Value!] = Uri.UnescapeDataString(parsedValue.Value.Value!);

I wonder why TryParseValue didn't return false?

Would you like to contribute a fix for this?

@Tratcher Tratcher added help wanted Up for grabs. We would accept a PR to help resolve this issue good first issue Good for newcomers. bug This issue describes a behavior which is not expected - a bug. labels Nov 11, 2022
@korteksz
Copy link
Contributor

Hi @Tratcher,

I would like to try to fix it as my first contribution if it is not a problem.

@Tratcher
Copy link
Member

@korteksz sure, first write the test and use that to figure out what the root issue is.

@korteksz
Copy link
Contributor

korteksz commented Nov 12, 2022

@Tratcher

It's probably coming from this line:

store[parsedName.Value.Value!] = Uri.UnescapeDataString(parsedValue.Value.Value!);

I wonder why TryParseValue didn't return false?

I think the problem is that if you have a cookie like errorcookie=dd,:("sa; then it gets parsed currently like:
Key: errorcookie Value: dd -> because it parses the cookie until it doesn't find a non-cookie character, in this case the ',' char. Then the while loop keeps iterating further until the last character which is a ';'. As far as this is a separator and we are at the end of the input value and because supportsMultipleValues is true we return true at the end, however our parsedName and parsedValue is null.

Update:
I've got a fix for that, but I don't know if its really appropriate and I don't know how should I proceed with the contribution. I assume I should commit my changes to the forked repo, but don't know for example how the review is happenning etc.

@adityamandaleeka
Copy link
Member

@korteksz If you've got questions about the implementation, feel free to drop them here. Or you can just open a pull request with your proposed change (and include a test) and the team will review it and give you feedback. Guidance for how to do that is here: https://github.com/dotnet/aspnetcore/blob/main/CONTRIBUTING.md#how-to-submit-a-pr

Thanks for contributing!

korteksz added a commit to korteksz/aspnetcore that referenced this issue Nov 16, 2022
….TryParseValues() method to prevent parsing strings wrong which contain separator characters. Reported by this issue: dotnet#45014
@adityamandaleeka adityamandaleeka added this to the 8.0-preview1 milestone Nov 16, 2022
korteksz added a commit to korteksz/aspnetcore that referenced this issue Nov 17, 2022
…erShared.TryParseValues() method to prevent parsing strings wrong which contain separator characters. Reported by this issue: dotnet#45014"

This reverts commit a5ee158.
@Tratcher Tratcher self-assigned this Dec 1, 2022
Tratcher pushed a commit that referenced this issue Dec 1, 2022
@cnblogs-dudu
Copy link
Contributor

Same issue in .NET 7.0.1.

@cnblogs-dudu
Copy link
Contributor

The PR #45127 disappeared in the release .NET 7.0.1, please see CookieHeaderParserShared.cs#L29

@Tratcher
Copy link
Member

@cnblogs-dudu this was only fixed in 8.0, not 7.0. Bug fixes are not automatically backported, you'd need to demonstrate that this issue is blocking your development. Do you understand why this cookie has invalid data, and how to avoid it or work around it?

@cnblogs-dudu
Copy link
Contributor

@Tratcher There are lots of Nullable object must have a value error logs in our asp.net core app when upgrading from .NET 6 to .NET 7.

System.InvalidOperationException: Nullable object must have a value.
   at Microsoft.Net.Http.Headers.CookieHeaderParserShared.TryParseValues(StringValues values, IDictionary`2 store, Boolean enableCookieNameEncoding, Boolean supportsMultipleValues)
   at Microsoft.AspNetCore.Http.RequestCookieCollection.ParseInternal(StringValues values, Boolean enableCookieNameEncoding)
   at Microsoft.AspNetCore.Http.Features.RequestCookiesFeature.get_Cookies()
   at Microsoft.AspNetCore.Authentication.Cookies.ChunkingCookieManager.GetRequestCookie(HttpContext context, String key)
   at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.ReadCookieTicket()
   at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.HandleAuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)

@kchinburarat
Copy link

kchinburarat commented Dec 19, 2022

I got same issue
image

eventdata.Exception.StackTraceString: at Microsoft.Net.Http.Headers.CookieHeaderParserShared.TryParseValues(StringValues values, IDictionary`2 store, Boolean enableCookieNameEncoding, Boolean supportsMultipleValues)
   at Microsoft.AspNetCore.Http.RequestCookieCollection.ParseInternal(StringValues values, Boolean enableCookieNameEncoding)
   at Agoda.Webgate.Services.MessageSender.CookieNamesHelper.GetIncomingCookieCollectionNames(HttpContext httpContext) in /build/Src/Agoda.Webgate.Services/MessageSender/WebgateMessage/CookieNamesHelper.cs:line 69
   at Agoda.Webgate.Services.MessageSender.WebgateMessageBuilder.BuildWebgateMessage(Int64 elapsedTime, HttpContext httpContext) in /build/Src/Agoda.Webgate.Services/MessageSender/WebgateMessage/WebgateMessageBuilder.cs:line 31
   at Agoda.Webgate.Services.MessageSender.WebgateMessageSender.Send(Int64 latency, HttpContext httpContext) in /build/Src/Agoda.Webgate.Services/MessageSender/WebgateMessage/WebgateMessageSender.cs:line 48
   
eventdata.Exception.Source: System.Private.CoreLib

System.Private.CoreLib: Nullable object must have a value.
  

Could you please release a fix version in .NET 7!! @Tratcher

@Tratcher
Copy link
Member

Noisy error logs are not sufficient justification for a patch. There needs to be a functional business impact.

A) Are these legitimate requests?
B) Why do they contain invalid data in their cookies?
C) Is there a viable workaround?
D) What impact is this having on your business?

It should be possible to work around this by checking the cookie header first for known invalid data and removing it or terminating the request.

@ghost ghost locked as resolved and limited conversation to collaborators Jan 18, 2023
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Aug 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions bug This issue describes a behavior which is not expected - a bug. good first issue Good for newcomers. help wanted Up for grabs. We would accept a PR to help resolve this issue
Projects
None yet
8 participants