Closed joonas-fi closed 3 years ago
Will fix it in this weekend. Thanks for reporting.
@joonas-fi: both issues are addressed. Please see #61 and #62.
All changes are published in v0.5.0.
Thanks for fast response!
I'm terribly sorry I didn't communicate myself well, but the place I linked to was only one of the places where the HTTP request path is directly used as a FS path. There's another place here: https://github.com/yookoala/gofast/blob/b30b52d0e86df28db57c447fb749ac97eb8c3529/session.go#L348
Disclaimer: I'm not saying this second place is the last place that has a vulnerability. I found these two by quickly looking, but if there's more places that take filesystem paths from HTTP request those should be investigated as well. I'll try looking.
Why no responsible disclosure
First off, I wanted to proceed with a responsible disclosure but:
The vulnerability
https://github.com/yookoala/gofast/blob/e5eda92ffb0e1f2aeada38c3174c0d1d9adeb2da/session.go#L227
This line takes remote user controllable path from HTTP request and appends it via
filepath.Join()
(it does relative-to-absolute translation) to a file path, now making it a legit file path from now on.Now, given user code:
And an attacker sending a HTTP request:
(curl would normalize the path without
--path-as-is
)Because the handler also serves static files, I am able to steal anything from the filesystem (even ENV vars from
/proc/self/environ
that sometimes are used to store secrets).If I add logging, the above request would show up as:
More on this vulnerability: https://owasp.org/www-community/attacks/Path_Traversal
Other observations
Ineffectual code
https://github.com/yookoala/gofast/blob/e5eda92ffb0e1f2aeada38c3174c0d1d9adeb2da/session.go#L218
This is ineffectual, as
req.Params["SCRIPT_FILENAME"]
is overwritten a few lines laterPerformance observation
https://github.com/yookoala/gofast/blob/e5eda92ffb0e1f2aeada38c3174c0d1d9adeb2da/session.go#L210
This compiles a regex on every request. It might be more performant to compile the regex only once (outside of this function). There's another place also that compiles a regex on every request.