Server-Side Request Forgery (SSRF) in gogs/gogs
Reported on
Jul 17th 2021
✍️ Description
In 2018, this issue was created to address a SSRF vulnerability in gogs wherein an attacker could have gogs send requests to network-internal hosts - a patch for this was released (see diff) and no queries about the SSRF issue seem to have been raised again since (from what I can tell). The patch that was released is a blacklist-based one, this isn't a bad idea in all cases but in this particular case; the blacklist does not cover all resolutions of localhost in quite a few scenarios. The vulnerable code is as follows:
var localHostnames = []string{
"localhost",
"127.0.0.1",
"::1",
"0:0:0:0:0:0:0:1",
}
As it does not account for the fact that 127.*.*.*
resolves to localhost too.
🕵️♂️ Proof of Concept
- Navigate to
https://try.gogs.io/repo/migrate
. - Under 'clone address' enter
http://127.1.33.7:3306/
. - Fill in the rest of the text areas and proceed.
- If the repository was created, port
3306
was open (MySQL) and if not, it was closed. (an error in this case would beMigration failed: clone: exit status 128 - fatal: unable to access 'http://@127.1.33.7:[closed_port]/': Failed connect to 127.1.33.7:[closed_port]; Connection refused
).
💥 Impact
This vulnerability is capable of allowing attackers to conduct internal port scans.
(please note that the SSRF shown here is a 'blind ssrf' and attackers, from what I can tell, would not gain any sensitive information outside of the open/closed status of a given port).
Occurrences
webhook.go L121-L136
var localHostnames = []string{
"localhost",
"127.0.0.1",
"::1",
"0:0:0:0:0:0:0:1",
}
// isLocalHostname returns true if given hostname is a known local address.
func isLocalHostname(hostname string) bool {
for _, local := range localHostnames {
if hostname == local {
return true
}
}
return false
}
@admin this was invalidated by mistake, could it be reopened?
@admin Is there any way that the Gogs maintainer (dummy issue + security@gogs.io
) could be re-notified as I think something went wrong during the accidental invalidation that might've caused them to not see this (the gogs/gogs repository is pretty active) and the vulnerability is still valid on the current Gogs version?
@michaellrowley - of course, I have just re-sent an e-mail to the maintainers but got a hard bounce when sending it.
It might be worth just sending them a personal e-mail with the URL for the report, as they will be able to gain access once they have signed up.
Let me know if you have any issues with this! ♥️
That's strange - I'll try sending them an email like you suggest and see if I can get the link to them.
Putting this here for issue-tracking: https://github.com/gogs/gogs/issues/6754
Hi, thanks for getting this validated - I've opened a pull request (#6812) that should fix this but I've never written code in Go before so there may be some errors in my style, syntax, or logic that needs fixing although I have tested this Gist so I'm fairly confident in the implementation details.
Please wait until the "Confirm Fix" button at which point a patch release has been made for users to upgrade. Just FYI that I plan to patch another issue https://github.com/gogs/gogs/issues/6810 together so might need to wait for a bit longer.
No problem, if there's anything I can do to help with the #6810 patch let me know!