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

compress/gzip: Reader unable to parse headers with long comments #14639

Open
dsnet opened this issue Mar 4, 2016 · 7 comments
Open

compress/gzip: Reader unable to parse headers with long comments #14639

dsnet opened this issue Mar 4, 2016 · 7 comments
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@dsnet
Copy link
Member

dsnet commented Mar 4, 2016

Using go1.6

RFC 1952 for gzip does not specify a length for the comment and name fields.

If FCOMMENT is set, a zero-terminated file comment is
present. This comment is not interpreted; it is only
intended for human consumption. The comment must consist of
ISO 8859-1 (LATIN-1) characters. Line breaks should be
denoted by a single line feed character (10 decimal).

The current implementation is inconsistent:

  • gzip.Writer permits the writing of any length comment/name string in gzip.Header.
  • gzip.Reader fails to read any comment/name string in gzip.Header longer than 511 bytes.

Playground example: https://play.golang.org/p/Zvjf8Q7jXe
Change 512 to 511 in the example, and it works again.

This causes issues reading gzip files produced by GZinga, which produces syntactically valid gzip files, but abuses the comment field to store meta data.

Update: I have no intention of fixing this unless there is someone who needs this functionality. Whatever fix we do will need to be careful that we don't introduce a potential vector for DOS attacks since gzip is a common Transfer-Encoding in HTTP. We don't want an infinitely long comment to cause a server to allocate an infinite amount of memory.

@dsnet
Copy link
Member Author

dsnet commented Apr 22, 2017

Bumping up milestone since #20083 provides good evidence that this is a real issue.

@dsnet dsnet modified the milestones: Go1.10, Unplanned Apr 22, 2017
@gopherbot
Copy link

Change https://golang.org/cl/53637 mentions this issue: compress/gzip: permit parsing of GZIP files with long header fields

@dsnet
Copy link
Member Author

dsnet commented Nov 8, 2017

Pushing to Go1.11 milestone... but I think a more general API for resource limitation might be the better approach. See #20169 for some discussion.

@dsnet dsnet modified the milestones: Go1.10, Go1.11 Nov 8, 2017
@dsnet dsnet modified the milestones: Go1.11, Unplanned Feb 16, 2018
@philippfrank
Copy link

@dsnet This is still an issue. Did it go under?

@dsnet
Copy link
Member Author

dsnet commented Sep 5, 2020

Running the snippet on Go1.15 clearly shows it's still an issue.

Huh, apparently I had a fix for this that I never submitted: https://golang.org/cl/53637

@philippfrank
Copy link

@dsnet Okay, any chance you can push that forward? I am using gzip.NewWriter() to compress arbitrary text files (up to 1GB in size) while being unable to uncompress those using the same gzip.NewReader().

For anyone else having that issue: a pragmatic solution might be to copy gunzip.go and adjust the maximum buffer size manually. It seems several other gzip modules out there have that exact same issue (because they copied the stdlib code).

@dsnet
Copy link
Member Author

dsnet commented Sep 7, 2020

Having reviewed my CL, the reason I didn't push it through is because of concerns with this feature being an trivial avenue for denial-of-service attack where a malicious GZIP file could cause a server to allocate arbitrary amounts of memory.

We have several options:

  1. We could immediately permit parsing of small headers (I proposed up to 32KiB to match the window size of the DEFLATE algorithm itself). However, this won't help use-cases that abuse the comment field to store machine-parsable information where it can easily exceed 32KiB.
  2. Add a new Reader.MaxFieldSize method so that the user can opt-in to parsing larger headers. Use of this option would still be a bit odd, since you would have to do something like:
var zr gzip.Reader
zr.MaxFieldSize(math.MaxInt32)
if err := zr.Reset(r); err != nil {
    ... // handle err
}
... // make use of zr.Header.Comment

Since this would probably require an API change, I'm adding the NeedDecision label.
\cc @FiloSottile since he's probably interested in any possible DOS-related issues.

@dsnet dsnet added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Sep 7, 2020
@rsc rsc unassigned dsnet Jun 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

4 participants