A security flaw, CVE-2024-53859, was found in the go-gh Go module—the common package used for interacting with the GitHub CLI (gh) and the GitHub API. This bug could accidentally leak your authentication tokens (used for GitHub.com or GitHub Enterprise) to non-GitHub servers, especially when running code inside a GitHub Codespace.

If you use or ship tools built with go-gh (before version 2.11.1), your tokens could be sent to the wrong host. This vulnerability has a broad impact because those tokens usually grant high privileges and access to your repositories.

In this post, we break down how the bug works, who is affected, how to exploit it, and how to secure your tokens now.

Why This Matters

Tokens (GITHUB_TOKEN, GH_TOKEN, etc.) give programs access to your GitHub account or enterprise. They should only be sent to trusted hosts—never to outside or malicious servers.

For GitHub Enterprise Server: Use GITHUB_ENTERPRISE_TOKEN or GH_ENTERPRISE_TOKEN

But, before v2.11.1, the function handling this (auth.TokenForHost) could give out your GITHUB_TOKEN to any host, not just github.com, when running inside a Codespace.

Here’s a simplified version of the code that caused the problem (cleaned up for readability)

// In go-gh before v2.11.1
func TokenForHost(hostname string) (string, error) {
    // Codespaces magic: uses GITHUB_TOKEN not just for github.com!
    if runningInCodespaces() {
        token := os.Getenv("GITHUB_TOKEN")
        if token != "" {
            return token, nil
        }
    }

    // Intended logic: check which host, use right env var
    switch hostname {
    case "github.com", "ghe.com":
        token := os.Getenv("GITHUB_TOKEN") // Should only check for these hosts!
        if token != "" {
            return token, nil
        }
    // Enterprise...
    default:
        token := os.Getenv("GITHUB_ENTERPRISE_TOKEN")
        if token != "" {
            return token, nil
        }
    }
    return "", errors.New("token not found")
}

The problem: *Any* hostname inside a Codespace could get the GITHUB_TOKEN env, no matter if it was actually a GitHub server.

What Could Go Wrong?

If a program using go-gh asks for a token for malicious.example.com or even an internal host, *inside a Codespace*, it would get your real GitHub token.

If that tool then sends a request to that untrusted host with the token, your token is now leaked.

Developer runs a tool or script inside a Codespace.

2. That tool uses go-gh to “connect” to their own server (not GitHub), maybe for some self-hosted feature.

Vulnerable version: go-gh returns their live GITHUB_TOKEN.

5. If that tool sends the token along in an HTTP header, files.example.com receives the personal or repo-scoped GitHub access token.
6. Result: An attacker controlling files.example.com could take over the developer's GitHub account or steal code.

Here’s a simple proof-of-concept to demonstrate the leak

package main

import (
    "fmt"
    "os"
)

// Mock version of the vulnerable function from go-gh
func TokenForHost(hostname string) string {
    // Simulate codespace environment
    if os.Getenv("CODESPACES") == "true" {
        return os.Getenv("GITHUB_TOKEN")
    }
    return ""
}

func main() {
    // Simulate being in Codespaces
    os.Setenv("CODESPACES", "true")
    os.Setenv("GITHUB_TOKEN", "super-secret-token")
    token := TokenForHost("malicious.example.com")
    fmt.Println("Leaked token:", token)
}

Any programmer can adapt this to actually send the token in an HTTP request.

Your GitHub credentials (with all their repo and org access) might be sent to the wrong servers.

- Token theft could lead to repository takeovers, code/data leaks, or malicious commits.

Upgrade go-gh to version 2.11.1 or newer.

- Regenerate any tokens used inside Codespaces during the period you were running vulnerable code. (GitHub: How to reset tokens)
- Review your GitHub security log and organization audit logs for suspicious activity.

Secure Version Logic

From go-gh commit 9c60fe5, the safe version prevents generic token leakage:

if hostname == "github.com" || hostname == "ghe.com" {
    token = os.Getenv("GITHUB_TOKEN")
    if token != "" {
        return token, nil
    }
}

References

- Original Advisory on GitHub Security
- go-gh source code and PR with the fix
- NIST NVD entry for CVE-2024-53859

Stay safe. Keep your tokens private and your dependencies up to date!

*You read it here first: the plain-English walkthrough for CVE-2024-53859. Bookmark this post or share with your team!*

Timeline

Published on: 11/27/2024 22:15:05 UTC