Full Report
GitHub Enterprise Servers (GHES) is a locally hosted version of Github that teams can run. It runs functionality the same as the regular Github service and is written in Ruby. Reflections in Ruby are used for calling arbitrary functions on an Object. This works because there is an inheritance structure similar to that of JavaScript. By calling Kernel#send() on an object, arbitrary functions can be called on an object. The author decided to look into potential sinks where this could be called, since it's known to be an RCE sink. While doing research into the possible exploit methods, they noticed that RCE would require at least two controlled parameters - they didn't see any paths for one or zero. They found a case of reflection with zero inputs at Organizations::Settings::RepositoryItemsComponent. From there, they wrote a script to enumerate the available functions and variables that would be interesting to look at within the Ruby console. While testing this, they noticed a couple of weird things. First, even if there are required parameters for a call, the function can still be called with default values. Additionally, the object in question with reflection issues had 5K different functions!? While conducting local testing there GHES broke. While it was fixing itself up they decided to mess around on standard Github. The function nw_fsck() was calling spawn_git. This returned a list of environmental variables for the Github server itself! To the authors surprise, this contained a lot of production access keys. How did this happen!? Upon finding this, they reported the vulnerability to Github to fix up. Ruby on Rails uses a serialized session that is signed. If this can be tampered with then RCE can be trivially obtained using Ruby deserialization primitives, such as with iblue's technique. Having access to the keys is a terrible primitive as a result. The difference between a local and a global instance of Github is interesting in this context. Accessing data globally is scary and all angles must be considered, especially with things like Github Actions. The enumeration of exploit paths for the deserialization was interesting to me in the post as well. The bug itself was simple but finding a meaningful impact was very difficult. Overall, great post for a super impactful bug!
Analysis Summary
# Vulnerability: GitHub Enterprise Server Unsafe Reflection to RCE/Information Disclosure
## CVE Details
- **CVE ID:** CVE-2024-0200
- **CVSS Score:** 10.0 (Critical)
- **CWE:** CWE-470 (Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection'))
## Affected Systems
- **Products:** GitHub Enterprise Server (GHES) and GitHub.com
- **Versions:** GHES versions prior to 3.8.12, 3.9.7, 3.10.4, and 3.11.1
- **Configurations:** Systems where the `Organizations::Settings::RepositoryItemsComponent` or the `rid_key` parameter is accessible.
## Vulnerability Description
The vulnerability stems from an unsafe reflection pattern in Ruby. The web application used `Kernel#send()` on a Ruby object using a user-controllable parameter (`rid_key`) without sufficient validation. While a single controlled parameter usually limits an attacker to calling methods with zero arguments or default values, the researcher identified that calling `nw_fsck()` triggered an internal call to `spawn_git`. On GitHub.com, this inadvertently returned a list of over 1,200 production environment variables. On GHES, this primitive could be escalated to Remote Code Execution (RCE) by manipulating Ruby deserialization primitives or session signing keys.
## Exploitation
- **Status:** PoC available (detailed in research blog). No evidence of exploitation in the wild prior to the report.
- **Complexity:** Medium to High (requires specific knowledge of Ruby object methods to find a meaningful sink).
- **Attack Vector:** Network (Authenticated via organization settings).
## Impact
- **Confidentiality:** Total (Disclosure of all production environment variables, including secrets, access keys, and credentials on GitHub.com).
- **Integrity:** Total (Potential for RCE on GHES instances, allowing full system compromise).
- **Availability:** Total (RCE allows for complete service disruption).
## Remediation
### Patches
GitHub released security updates on January 16, 2024, to address this flaw in GHES:
- **GHES 3.8.12**
- **GHES 3.9.7**
- **GHES 3.10.4**
- **GHES 3.11.1**
### Workarounds
No formal workarounds are provided; users are strongly encouraged to update to the patched versions immediately. GitHub infrastructure (GitHub.com) was hotfixed on December 26, 2023.
## Detection
- **Indicators of Compromise:** Look for abnormal `rid_key` values in requests to the endpoint `/organizations/<org>/settings/actions/repository_items`.
- **Detection Methods:**
- Review web server access logs for the aforementioned path and parameter.
- Note that `rid_key` can be supplied in either the URL query string or the request body.
- Monitor for unauthorized credential rotation or unrecognized access using production-level service keys.
## References
- **Vendor Advisory:** [https://github.blog/2024-01-16-rotating-credentials-for-github-com-and-new-ghes-patches/](https://github.blog/2024-01-16-rotating-credentials-for-github-com-and-new-ghes-patches/)
- **Technical Write-up:** [https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/)
- **CVE Record:** [https://www.cve.org/CVERecord?id=CVE-2024-0200](https://www.cve.org/CVERecord?id=CVE-2024-0200)