Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/pentesting-ci-cd/github-security/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,76 @@ Hardening guidelines for services running external tools:
- Execute tools in tightly isolated sandboxes with no sensitive environment variables mounted
- Apply least‑privilege credentials and filesystem isolation, and restrict/deny outbound network egress for tools that don’t require internet access

## Git Push Infrastructure & GHES Security

A Git server may treat `git push -o <value>` as harmless client metadata while internal backend services later parse it as **trusted security configuration**. If any service serializes user-controlled push options into a delimiter-based internal header, an attacker with **push access** may be able to **inject extra fields**, **override policy booleans**, reach **debug / enterprise-only code paths**, and even influence **hook execution**.

### Delimiter injection into trusted internal metadata

If user-controlled values are copied into an internal format such as `key=value;key=value` without escaping reserved delimiters, a push option can terminate its expected field and append new ones:

```bash
git push -o 'x;security_flag=bool:false' origin HEAD
```

Common exploitation conditions:

- The transport format uses a reserved delimiter such as `;`
- User-controlled values are copied verbatim into the internal header
- The receiver splits the header and inserts fields into a map/dictionary
- **Duplicate keys are accepted** and the last value silently wins
- Downstream services trust the parsed metadata as authenticated internal state

This is especially dangerous when the injected fields control **sandboxing, feature flags, branch protections, hook configuration, or debug modes**.

### Escalation patterns from metadata injection to RCE

Useful patterns abstracted from the GitHub/GHES X-Stat bug chain:

1. **Policy override via duplicate keys**: inject a second copy of a security-sensitive field later in the header to replace the original value.
2. **Sandbox bypass via mutable environment markers**: if sandbox selection depends on request metadata such as `rails_env`, overriding it may switch execution to a development or direct-exec path.
3. **Debug-mode injection**: enabling flags such as operator/debug mode can disclose which validation and hook stages are reached, helping to identify missing prerequisites and hidden feature gates.
4. **Dormant feature activation**: environment or enterprise-mode booleans transported in the same metadata may enable code paths that are normally disabled on some deployments.
5. **Hook-path traversal**: if the server accepts both a hook base directory and a relative script path from mutable metadata, a simple path join may resolve to an arbitrary existing executable.

For custom hook runners, verify all of the following before considering them safe:

- The final resolved path is canonicalized
- The canonical path is still inside the approved hook directory
- The server uses allowlisted hook IDs instead of client-supplied filesystem paths
- Production binaries do not contain reachable unsandboxed development execution paths

### GHES / multi-tenant impact

This class of bug does **not** require `root` to be critical. Code execution as a service account such as `git` may still expose:

- All repositories hosted by the node/appliance
- Internal service configuration and secrets
- Cross-tenant repository access on shared storage nodes
- Full compromise of GHES appliances where the Git service account has broad filesystem access

### Detection and technical hardening

Hunting ideas:

- Inspect **Git-over-SSH push options** for reserved delimiters such as `;`
- Alert on push options or internal telemetry containing field names related to **environment mode, hook directories, hook JSON, operator/debug flags, or enterprise-mode selectors**
- Detect **duplicate security-critical keys** inside internal metadata headers if the header is logged or can be reconstructed from traces
- Alert on unexpected **custom pre-receive hook execution** or debug/operator output during pushes
- Monitor hook runners for execution of binaries outside approved hook directories
- Verify that resolved hook paths remain under the configured hook root after canonicalization

Engineering guidance:

- Treat **all metadata derived from push options as untrusted input**
- Use structured serialization instead of delimiter-based ad-hoc headers
- Reject duplicate security-sensitive fields instead of applying last-write-wins semantics
- Make downstream services re-validate security-critical state instead of trusting upstream metadata blindly
- Remove or permanently disable development / non-production execution paths from production builds

> [!NOTE]
> CVE-2026-3854 is a good public example of this pattern in GitHub/GHES: SSH `git push -o` input reached an internal `X-Stat` header, security-sensitive duplicate keys were accepted, sandbox selection depended on mutable metadata, and custom-hook path resolution allowed traversal to an existing executable.

## Branch Protection Bypass

- **Require a number of approvals**: If you compromised several accounts you might just accept your PRs from other accounts. If you just have the account from where you created the PR you cannot accept your own PR. However, if you have access to a **Github Action** environment inside the repo, using the **GITHUB_TOKEN** you might be able to **approve your PR** and get 1 approval this way.
Expand Down Expand Up @@ -401,6 +471,8 @@ For more info check [https://www.chainguard.dev/unchained/what-the-fork-imposter

## References

- [Wiz Research: CVE-2026-3854: GitHub RCE Through X-Stat Push-Option Injection](https://www.wiz.io/blog/github-rce-vulnerability-cve-2026-3854)
- [GitHub: Securing the git push pipeline: Responding to a critical remote code execution vulnerability](https://github.blog/security/securing-the-git-push-pipeline-responding-to-a-critical-remote-code-execution-vulnerability/)
- [How we exploited CodeRabbit: from a simple PR to RCE and write access on 1M repositories](https://research.kudelskisecurity.com/2025/08/19/how-we-exploited-coderabbit-from-a-simple-pr-to-rce-and-write-access-on-1m-repositories/)
- [Rubocop extensions (require)](https://docs.rubocop.org/rubocop/latest/extensions.html)
- [Authenticating with a GitHub App (JWT)](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app)
Expand Down