Skip to content

Bypassing SSRF protections in project imports using octal and other representations of 127.0.0.1

Title: SSRF vulnerability in gitlab.com via project import.

Weakness: Server-Side Request Forgery (SSRF)

Severity: Medium (5.4)

Link: https://hackerone.com/reports/215105

Date: 2017-03-21 14:12:33 +0000

By: @Edio

Details: Dear GitLab bug bounty team,

Summary

It appears as though the fix to !17286 can be easily bypassed. You have blocked the usage of http://127.0.0.1, http://localhost/, etc., but http://0177.1/ and http://0x7f.1/, for instance, can still be used to scan internal ports.

Error importing repository http://0177.1:22/ into {username}/{project} - Cloning into bare repository '[REPOS PATH]/{username}/{project}.git'...
fatal: unable to access 'http://0177.1:22/': Recv failure: Connection reset by peer

Admittedly, you have restricted the use of certain ports, but I still believe this needs to be fixed.

Fix

Block decimal, octal and hex localhost notation.

Best regards, Ed

Timeline: 2017-03-21 16:54:00 +0000: @Edio (comment) The issue lies in lib/gitlab/url_blocker.rb:

def blocked_url?(url)
        return false if url.nil?
        blocked_ips = ["127.0.0.1", "::1", "0.0.0.0"]
        blocked_ips.concat(Socket.ip_address_list.map(&:ip_address))

Link to source code: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/url_blocker.rb#L10-14


The reporter goes on to suggest a fix of adding these values to the IP block list. This will not work, however, as the destination hostname is resolved prior to being run through the blocklist.

What's happening is that some hosts/libraries resolve 0177.1 and 0x7f.1 to 127.0.0.1 while others return nil. For hosts that resolve properly the attack is blocked, but for those that return nil the request is allowed to proceed.

Blocking on hostnames that exist but resolve to nil may be the obvious solution, however this would block project saves on hosts that have temporarily lost DNS. Another option would be to block imports from nil only in the service and not for project saves. You could still save the project but the import would fail... as it would fail anyways if the hostname does not resolve.