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

Handle invalid Accept header values properly #2316

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bonprosoft
Copy link

NegotationFormat raises out-of-range access to an offer string with some invalid HTTP Accept header values. It happens with the current master: 3315353 .

For example, the following header causes an internal server error.

Accept: application/json2

I also found NegotationFormat returns an inappropriate result with some invalid Accept values. Please refer to the TestContextNegotiationFormatWithInvalidAccept.

So I updated the implementation to handle those invalid values properly.


I found that the wildcard support for content negotiation was introduced in #1112.
But it seems there is no discussion about the old implementation.
I am sorry if I missed something.

@codecov
Copy link

codecov bot commented Apr 7, 2020

Codecov Report

Merging #2316 into master will not change coverage by %.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #2316   +/-   ##
=======================================
  Coverage   98.39%   98.39%           
=======================================
  Files          41       41           
  Lines        2304     2304           
=======================================
  Hits         2267     2267           
  Misses         21       21           
  Partials       16       16           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3315353...c226883. Read the comment docs.

Copy link

@rickb777 rickb777 left a comment

Choose a reason for hiding this comment

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

This PR does not finish the necessary work. Each media-range can include a quality factor, e.g. text/xml;q=0.5 and these alter the preference order.

The algorithm should be:

  • split the header on ',' into a list of media-ranges.
  • foreach media-range, split on ';' into parts
  • split the first part on '/' as done in this PR
  • find the q quality option from the remaining parts; if absent the default is q=1
  • sort all the parts by quality, without altering the order of those that have the same q
  • match the sorted list against the offered content

Note that the RFC allows other options as well as q.

@@ -1047,19 +1047,27 @@ func (c *Context) NegotiateFormat(offered ...string) string {
return offered[0]
}
for _, accepted := range c.Accepted {
// According to RFC 2616, media-range = ( "*/*" | ( type "/" "*" ) | ( type "/" subtype ) )

Choose a reason for hiding this comment

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

need to update this to RFC7231 section 5.3.2
https://tools.ietf.org/html/rfc7231#section-5.3.2

@rickb777
Copy link

rickb777 commented Oct 23, 2020

As it happens, there's a bunch of existing code to parse Accept headers such as my own
https://pkg.go.dev/github.com/rickb777/[email protected]#Accept

It's also MIT licence so we could pull the code over (and acknowledge).

@bonprosoft
Copy link
Author

Thank you for your comment.
I'm really sorry for the delay in my response.

My intention of the PR is to prevent gin from having out-of-range access when an invalid HTTP accept header is given.
If someone sends another PR to implement RFC 7231 correctly, then I will close this PR.

@rickb777
Copy link

I am hoping to have the time to create a patch based on https://pkg.go.dev/github.com/rickb777/[email protected]#Accept, although that code needs to reach v1 first (a bit more testing effort needed there).

@rickb777
Copy link

rickb777 commented Nov 8, 2020

I'm still developing https://pkg.go.dev/github.com/rickb777/negotiator, which has changed a lot since I last posted. It's now v0.9.0 and even now not yet stable. However, it is able to work with Gin, which is a good thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants