@orangetw identified a bypass of the protections implemented in GitHub Enterprise to prevent Same-Site Request Forgery (SSRF) via a repository’s webhooks. The blacklist of restricted internal addresses could be bypassed using an overlooked alternative representation for localhost. With this bypass, an attacker could make requests to internal services that are intended to be restricted from webhooks.
The webhook POST body payload is not fully attack controlled since it is prepended with a request parameter string. As a result, it could not be used directly to make arbitrary HTTP requests to potentially exploitable internal services such as Redis or Memcached. To circumvent this, @orangetw identified yet another SSRF vulnerability within another service on GitHub Enterprise that is only internally accessible. In combination, an attacker could craft requests to the local Redis service.
With full access to write values to the local Redis instance, @orangetw was able to store a value that would later be retrieved by GitHub Enterprise and used as input to a
Marshal.load call. As noted by the Ruby documenation for
Marshal.load, this can result in code execution.
We took a number of steps to fix this issue and prevent future vulnerabilities. First, we added a stricter blacklist to the HTTP client that repository webhooks use to make requests. Additionally, we now prevent webhooks from accessing internal services using the local firewall. Finally, the internal service containing the second SSRF has been restricted to only the endpoints used by GitHub Enterprise.
This issue was fixed in GitHub Enterprise 2.8.7, 2.7.11, 2.6.16, 2.5.21, and 2.4.23.