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

fix lack of escaping of filename in Content-Disposition #3556

Merged
merged 3 commits into from
May 29, 2023

Conversation

motoyasu-saburi
Copy link
Contributor

context.go Outdated
@@ -1056,7 +1056,7 @@ func (c *Context) FileFromFS(filepath string, fs http.FileSystem) {
// On the client side, the file will typically be downloaded with the given filename
func (c *Context) FileAttachment(filepath, filename string) {
if isASCII(filename) {
c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)
c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+strings.Replace(filename, "\"", "\\\"", -1)+`"`)

Choose a reason for hiding this comment

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

This can fix this specific situation (that enables RFD attack) but what about using filePath#Clean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried using that method,
but the " was not escaped (or URL Encoded), so The vulnerability was not fixed.

Choose a reason for hiding this comment

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

But since it's for file reading those quotes will be needed? File params would be readable with or without it, isn't?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@fabricioereche

Perhaps you are confusing the file name with the file path.
There may be some misunderstandings, so I will add to this.


The first thing to escape is the filename. Not filepath.

The second thing, The Filename escape requirements are then as follows

  • " --> %2F, \"
  • \r --> %0D, \\r
  • \n --> %0A, \\n

The third thing,
This line is the process of "escaping the 'file name at download time' on the HTTP Response Header.
In other words, filepath is irrelevant.

(The part that actually reads the file is the following line (filepath) )
https://github.com/gin-gonic/gin/pull/3556/files#diff-552f47512a00afe5fc6850cc9ddc830a6daeca162750e50aab4ed549685e0253R1063


But since it's for file reading those quotes will be needed? File params would be readable with or without it, isn't?

This is answered by the third matter mentioned above.
This tells the Request side to "download the file with this kind of file name".
It is not the file path to be read by the Server side.

Does this answer your question?

fabricioereche
fabricioereche previously approved these changes Apr 11, 2023
@zpavlinovic
Copy link

Is there a plan for this fix to be merged in?

@jerbob92
Copy link

Is there a reason we can't use url.QueryEscape here? Just like in the UTF-8 version?

For my own implementation I had copied the implementation from Go http/multipart, so:

var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func escapeQuotes(s string) string {
	return quoteEscaper.Replace(s)
}

h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, escapeQuotes(fieldname), escapeQuotes(filename)))

@motoyasu-saburi
Copy link
Contributor Author

motoyasu-saburi commented May 12, 2023

@jerbob92

Is there a reason we can't use url.QueryEscape here? Just like in the UTF-8 version?

Both will solve the security issue.
First, the requirement for encoding by URL Encode is Whtat's WG > multipart/form-data requirements.

In this case, the requirement to "perform URL Encoding" is not (strictly) the same as that of What's WG, since this is a response.

On the other hand, there is no clear escape requirement specified in the RFC 6266 either.
https://datatracker.ietf.org/doc/html/rfc6266#section-5

After that, we checked about 80 systems of several services, WebFrameworks, Browsers, etc., and found that most of them use BackSlash encoding for response headers, so we chose BackSlash style escaping and implemented it this time.

(For example, Gmail file downloads would have been in backslash format.)

In my personal opinion,
either is honestly fine, since the root cause is that the Content-Disposition specification is not strict.

@jerbob92
Copy link

@motoyasu-saburi I tested some different things and couldn't get around this fix, so for the least invasive change, I would indeed go for the string replacer version, and not the url.QueryEscape. I would go with the escapeQuotes method from http/multipart just so that the logic is matched.

fix backslashes before backquotes were not properly escaped problem.
@motoyasu-saburi
Copy link
Contributor Author

@jerbob92 Thank you,
As you said, there was a problem.
I tried to fix it, Could you review it?

@jerbob92
Copy link

@motoyasu-saburi
I tried the escape trick too, but it didn't work, Chrome just transformed it into an underscore, so filename becomes tampering_field.sh_, so that's why I didn't see it as a real problem. But I think the current fix is the best solution.

@motoyasu-saburi
Copy link
Contributor Author

@fabricioereche
I have made some corrections after receiving your approval,
so could you please review it again?

MHSanaei added a commit to MHSanaei/3x-ui that referenced this pull request May 15, 2023
Gin Web Framework does not properly sanitize filename parameter of Context.FileAttachment function

References
gin-gonic/gin#3555
gin-gonic/gin#3556
https://pkg.go.dev/vuln/GO-2023-1737
alireza0 added a commit to alireza0/x-ui that referenced this pull request May 15, 2023
Gin Web Framework does not properly sanitize filename parameter of Context.FileAttachment function

References
gin-gonic/gin#3555
gin-gonic/gin#3556
https://pkg.go.dev/vuln/GO-2023-1737

Co-authored-by: MHSanaei <ho3ein.sanaei@gmail.com>
hamid-gh98 pushed a commit to hamid-gh98/x-ui that referenced this pull request May 15, 2023
Gin Web Framework does not properly sanitize filename parameter of Context.FileAttachment function

References
gin-gonic/gin#3555
gin-gonic/gin#3556
https://pkg.go.dev/vuln/GO-2023-1737

Co-authored-by: MHSanaei <ho3ein.sanaei@gmail.com>
Copy link

@hmert hmert left a comment

Choose a reason for hiding this comment

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

This fix is very important to us.

@motoyasu-saburi
Copy link
Contributor Author

Could you review PR ?
@thinkerou @appleboy

@adrianosela
Copy link
Contributor

Can we get this in @fabricioereche? Lot's of folks waiting for a patch for GHSA-2c4m-59x9-fr2g

@fabricioereche
Copy link

Can we get this in @fabricioereche? Lot's of folks waiting for a patch for GHSA-2c4m-59x9-fr2g

all set for me

@sm003ash
Copy link

Hi, when will this be merged and available in the next release? We use the gin framework at my workplace, and this CVE issue is urgent for us to fix, else we will have to migrate to another framework, which we don't want to do.

@thinkerou thinkerou added this to the v1.10 milestone May 24, 2023
@codecov
Copy link

codecov bot commented May 24, 2023

Codecov Report

Merging #3556 (ee5b2c9) into master (a889c58) will increase coverage by 0.38%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master    #3556      +/-   ##
==========================================
+ Coverage   98.63%   99.01%   +0.38%     
==========================================
  Files          42       42              
  Lines        3151     3153       +2     
==========================================
+ Hits         3108     3122      +14     
+ Misses         29       21       -8     
+ Partials       14       10       -4     
Flag Coverage Δ
99.01% <100.00%> (+0.38%) ⬆️
go-1.18 98.92% <100.00%> (+0.38%) ⬆️
go-1.19 99.01% <100.00%> (+0.38%) ⬆️
go-1.20 99.01% <100.00%> (+0.38%) ⬆️
macos-latest 99.01% <100.00%> (+0.38%) ⬆️
ubuntu-latest 99.01% <100.00%> (+0.38%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
context.go 97.98% <100.00%> (+<0.01%) ⬆️

... and 1 file with indirect coverage changes

@thinkerou
Copy link
Member

@appleboy please review, thanks!

@amandalal
Copy link

@appleboy @thinkerou Any updates on when this will be merged and when the next release will be available? Thank you!

@jclebreton
Copy link
Contributor

This PR is referenced in the Govulcheck database (https://pkg.go.dev/vuln/GO-2023-1737) and many people are waiting for the fix.

@AndrewSav
Copy link

@appleboy is there anything we can do to help move this forward? It has been almost 2 months with this vulnerability and no fix, people get anxious, feeling unprotected. A suggestion from me would be that if you cannot do the review and merge, could you possibly delegate it to @thinkerou? Many thanks!

@hmert
Copy link

hmert commented May 28, 2023

Unfortunately, we decided to move to another framework. For your security, take action.

@thinkerou thinkerou merged commit 2d4bbec into gin-gonic:master May 29, 2023
@thinkerou
Copy link
Member

wait #3620 thanks all!

@thinkerou thinkerou modified the milestones: v1.10, v1.9.1 Jun 1, 2023
@motoyasu-saburi motoyasu-saburi deleted the fix-rfd-vuln branch June 1, 2023 03:04
pvormste added a commit to pvormste/gin that referenced this pull request Jun 28, 2023
* fix lack of escaping of filename in Content-Disposition

* add test for Content-Disposition filename escaping process

* fix filename escape bypass problem
fix backslashes before backquotes were not properly escaped problem.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.