See how github compares to other vendors in security performance
A Server-Side Request Forgery (SSRF) vulnerability was identified in GitHub Enterprise Server that allowed a repository contributor to cause the appliance to issue requests to attacker-controlled internal hosts, which could be chained to achieve remote code execution on the appliance. The secret scanning validator for GCP service account credentials trusted the token endpoint embedded in a committed credential and issued a request to it without restricting the destination. Exploitation required an authenticated user with permission to push to a repository on an instance with GitHub Advanced Security and secret scanning validity checks enabled, a non-default configuration. This vulnerability affected GitHub Enterprise Server 3.20, 3.21, and 3.22 and was fixed in versions 3.20.9, 3.21.7, and 3.22.2. This vulnerability was reported through the GitHub Bug Bounty program.
A missing authorization vulnerability was identified in GitHub Enterprise Server that allowed a repository collaborator with write access to delete the current default branch through the GraphQL API and cause an attacker-controlled branch to become the new default. In repositories that required pull-request review but did not restrict branch deletion, this bypassed the review requirement and caused fresh clones and default-branch API requests to use attacker-controlled content. This vulnerability affected supported GitHub Enterprise Server releases in the 3.18, 3.19, 3.20, 3.21, and 3.22 series and was fixed in versions 3.18.16, 3.19.13, 3.20.9, 3.21.7, and 3.22.2. This vulnerability was reported via the GitHub Bug Bounty program.
Classroom 50 is a free and open-source tool for managing and grading programming assignments via GitHub. Prior to version 1.11.0, gh teacher download clones each student's assignment repository and then writes autograde artifacts (result.json and results.json) into the just-cloned working tree. The write followed symlinks, so a student who committed result.json or results.json as a symlink (materialized verbatim by git clone) could redirect the teacher's write to an arbitrary path — e.g. ~/.zshrc, ~/.ssh/authorizedkeys, a cron file, or an in-clone .git/hooks/ file that git subsequently executes. The written bytes are attacker-controlled (the student's uploaded release asset for result.json; student-chosen submit-tag names for results.json). This is an arbitrary file write leading to code execution as the teacher, whose gh token carries admin:org, repo, and workflow across the entire classroom organization. Version 1.11.0 contains a patch. Some workarounds are available. Avoid running gh teacher download against untrusted student repositories, or run it inside a disposable sandbox / container with no access to sensitive host files or credentials. Inspect cloned trees for symlinked, hardlinked, or special (result.json/results.json) entries before allowing the artifact-refresh step to run.
An authorization bypass vulnerability was identified in GitHub Enterprise Server that allowed any authenticated user of the instance to read the raw diff or patch of pull requests in private repositories without authorization. Access tokens for raw pull request diffs and patches were scoped to the repository name and pull request number rather than to a globally unique repository identifier, so an attacker who created a repository and pull request matching a target's repository name and pull request number could use a token for their own repository to retrieve the private pull request's contents. Exploitation required the attacker to know the target repository's name and a valid pull request number. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.17.21, 3.18.15, 3.19.12, 3.20.8, and 3.21.6. This vulnerability was reported via the GitHub Bug Bounty program.
A stored cross-site scripting (XSS) vulnerability was identified in GitHub Enterprise Server that allowed an authenticated attacker to inject arbitrary HTML attributes into rendered Markdown because the Markdown rendering pipeline rewrote quote characters in already-sanitized HTML without re-sanitizing the result. Crafted Markdown could abuse same-origin JavaScript gadgets to bypass Content Security Policy and gain control of the page DOM when viewed by another user. Successful exploitation could allow an attacker to read content visible to the victim, extract embedded CSRF tokens, perform state-changing actions as the victim, and exfiltrate data through same-origin writes. The payload could also propagate to repositories and organizations where the victim had write access. This vulnerability affected supported GitHub Enterprise Server releases in the 3.17, 3.18, 3.19, 3.20, 3.21, and 3.22 series and was fixed in versions 3.22.1, 3.21.6, 3.20.8, 3.19.12, 3.18.15, and 3.17.21. This vulnerability was reported via the GitHub Bug Bounty program.
A server-side request forgery (SSRF) vulnerability was identified in the notebook viewer of GitHub Enterprise Server. The notebook viewer validated the scheme and host of a user-supplied URL but did not validate the port, allowing requests to be directed to internal services listening on other ports of the same appliance. Response bodies were not returned to the requester, but response timing acted as an oracle that allowed instance secrets to be extracted character by character. An extracted secret could then be used in a separate interaction with an internal service to obtain remote code execution on the appliance. Exploitation required network access to the instance and was unauthenticated when private mode was disabled, or required any authenticated user when private mode was enabled. This vulnerability affected GitHub Enterprise Server versions 3.17 through 3.22 and was fixed in versions 3.22.1, 3.21.6, 3.20.8, 3.19.12, 3.18.15, and 3.17.21. This vulnerability was reported through the GitHub Bug Bounty program.
The commit-dist.yml workflow trusts an artifact-supplied branch name. An external contributor can exploit this trust boundary violation to push attacker-controlled dist/ content to a target repository branch.
A Server-Side Request Forgery (SSRF) vulnerability was identified in GitHub Enterprise Server that allowed remote code execution on the instance. Insufficient network isolation allowed malicious pre-receive hook code to impersonate an internal service and redirect trusted internal requests to a privileged service, leading to elevated code execution. Exploitation required pre-receive hook networking to be enabled and either site administrator privileges or write access to a repository containing a configured pre-receive hook. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.17.20, 3.18.14, 3.19.11, 3.20.7, and 3.21.5. This vulnerability was reported via the GitHub Bug Bounty program.
A time-of-check time-of-use race condition vulnerability was identified in GitHub Enterprise Server that allowed remote code execution. Exploitation required an authenticated user with write access to a repository and precise timing of concurrent upload requests. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.17.20, 3.18.14, 3.19.11, 3.20.7, and 3.21.5. This vulnerability was reported via the GitHub Bug Bounty program.
A server-side request forgery (SSRF) vulnerability was identified in GitHub Enterprise Server that allowed an unauthenticated attacker to cause the Manage API to send crafted outbound requests to an attacker-controlled host. An unauthenticated endpoint parsed an attacker-supplied cluster configuration and issued gateway-to-agent requests whose HMAC authenticated only a timestamp, not the request path or body. An attacker positioned to intercept the outbound request could capture this token and replay it against privileged management agent endpoints. High-availability deployments were not affected due to a topology restriction. This vulnerability affected GitHub Enterprise Server releases in the 3.17, 3.18, 3.19, 3.20, and 3.21 series and was fixed in versions 3.17.21, 3.18.15, 3.19.12, 3.20.8, and 3.21.6. This vulnerability was reported via the GitHub Bug Bounty program.
GitHub CLI (gh) is GitHub's official command line tool. Versions 2.28.0 through 2.97.0 bind the local listener created by gh codespace ports forward to all available network interfaces by default. While port forwarding is active, a service in a Codespace can therefore become reachable through the user's non-loopback local IP addresses by other hosts that can route to the user's machine. This behavior does not change the GitHub-side visibility of the Codespaces port. Instead, it exposes the forwarded service through a wildcard-bound listener on the user's local machine, even when the source Codespaces port remains private. Exploitation requires a network-adjacent attacker to reach the victim's machine while forwarding is active. This issue is fixed in version 2.98.0.
GitHub Copilot and Visual Studio Code Elevation of Privilege Vulnerability
Summary
A security vulnerability has been identified in GitHub CLI that could allow attestation verification bypass when using gh attestation verify with --signer-repo or --signer-workflow flags. GitHub CLI builds the certificate matcher from these flag values without escaping regex metacharacters, so a repository or workflow name is treated as a regular expression rather than a literal string. GitHub permits characters such as . in organization, repository, and workflow path names, and . is a regex wildcard, so a malicious actor can create a lookalike name that satisfies a matcher intended for a different, trusted signer.
Details
GitHub CLI constructs a regular expression from the --signer-repo and --signer-workflow values and matches it against the signing certificate's SAN (Subject Alternative Name) during Sigstore attestation verification. The user-supplied value is interpolated into the pattern without escaping regex metacharacters, so any metacharacter permitted in a GitHub path is interpreted as regex syntax instead of a literal character.
The most practical case is . , which GitHub allows in org/repo names and is a regex wildcard meaning "any single character." For example, an attacker-controlled repository named:
github/artifact.attestations-workflows
matches a verifier configured for the trusted signer:
github/artifact-attestations-workflows
because the unescaped . in the constructed pattern matches the - in the attacker's name (and any other single character at that position). This affected the --signer-repo and --signer-workflow flags but did not affect the --repo and --owner flags which include an exact string comparison.
In v2.97.0, the GitHub CLI escapes the user-supplied signer values before they are incorporated into the SAN matcher, so they are matched as literal strings.
Impact
The practical impact is limited, exploitation requires the attacker to create a plausible lookalike repository name and produce valid Sigstore attestations from it. This could undermine supply chain verification for CI/CD pipelines or policy gates that use these flags to pin trust to a specific signing workflow.
Remediation and Mitigation
1. Upgrade gh to v2.97.0 or later, which escapes signer values before matching. 2. As a workaround, use --repo or --owner flags instead of --signer-repo or --signer-workflow where applicable. 3. Manually inspect the signing certificate SAN in attestation output to confirm the signing workflow origin.
GitHub CLI (gh) is GitHub's official command line tool. Prior to version 2.97.0, multiple GitHub CLI commands printed externally controlled gist, API, pull request, release, codespace, skill, or agent-task content without neutralizing terminal escape sequences. An attacker who can influence that content can embed escape sequences that are interpreted by the terminal of a user who runs an affected command, with impact ranging from cosmetic manipulation of the title or on-screen content to, on some terminal emulators, command execution. This extends the same class of issue as CVE-2026-45803—which addressed only gh run view --log—to the other affected command paths. This issue is fixed in version 2.97.0.
Summary
A path traversal vulnerability has been identified in the GitHub CLI where some HTTP request URLs, REST API calls in particular, were built without properly escaping their variable path components. A value containing URL path metacharacters can alter the request path and cause gh to address a different resource than intended.
Details
Not all request URLs in the codebase were built with proper escaping of their variable path components. When a component is interpolated into the path without percent encoding, and that component contains URL path metacharacters, it breaks out of its intended segment and changes the effective request path.
In 2.97.0, request URLs are constructed in a safe manner, so a variable component can no longer escape its intended segment.
Impact
An attacker who can control a value that flows into a request path can cause gh to send the request to a different API endpoint than intended. This can lead the CLI to read or act on a resource other than the one the user meant to target.
Remediation and Mitigation
1. Upgrade gh to 2.97.0. 2. Be cautious when running gh against untrusted repositories or inputs whose names you do not control.
Summary
A security vulnerability has been identified in GitHub CLI where gh auth status could potentially print a portion of the authentication token in plaintext, depending on the lexical structure of the token.
Affected users: - Authenticated users who ran gh auth status (without the --show-token flag) with a token type whose format contains an underscore after the prefix. This includes fine-grained personal access tokens (githubpat) and GitHub App installation/user access tokens (ghs, ghu, e.g., ghs<APPID><JWT>), including the Actions GITHUBTOKEN. Classic tokens such as gho and ghp have an underscore-free body and are not affected.
Details
The vulnerability stems from the way GitHub CLI masks the authentication token when reporting authentication state:
1. A user runs gh auth status without --show-token, expecting the token to be fully masked. 2. The masking logic redacts only the characters that follow the last underscore in the token, instead of redacting everything after the token prefix. 3. The partially masked token is written to the command output, where it can be captured or shared.
Because gh auth status is a diagnostic command commonly run interactively and inside automated environments, the leaked token characters can end up in CI/CD job logs, terminal scrollback, screen recordings, screenshots, or pasted output shared in bug reports and support requests.
In v2.97.0, GitHub CLI fully masks the token in gh auth status output, preserving only the known token prefix and redacting the remainder unless --show-token is explicitly provided.
Impact
Running gh auth status in a context where the output is captured, logged, or shared could leak a portion of an affected token. The affected token types are fine-grained personal access tokens (githubpat) and GitHub App installation/user access tokens (ghs, ghu, e.g., ghs<APPID><JWT>), including the Actions GITHUBTOKEN. Installation and Actions tokens are short-lived, which narrows the window in which a recovered token could be reused. See GitHub credential types.
Remediation and Mitigation
1. Upgrade gh to v2.97.0. 2. Rotate any affected token whose masked gh auth status output may have been captured or shared: - Fine-grained personal access tokens (githubpat): regenerate the token from your account settings. See Managing your personal access tokens. - GitHub App installation/user access tokens (ghs, ghu, e.g., ghs<APPID><JWT>): these are short-lived and rotate automatically (See GitHub credential types). If you believe a token was captured while still valid, you can revoke it immediately using the Revoke an installation access token REST endpoint (DELETE /installation/token). To cut off a third-party app's access more broadly, suspend or uninstall the app from the web UI. See Reviewing and modifying installed GitHub Apps. - Actions GITHUBTOKEN: this token is automatically invalidated when the job finishes, so no manual revocation is normally required. See GitHub credential types. 3. Until you can upgrade, avoid running gh auth status in contexts where the output is captured or shared, and manually redact the token line before sharing any output.
A denial of service vulnerability was identified in GitHub Enterprise Server that allowed an unauthenticated attacker to cause excessive CPU consumption and exhaust the pool of request-handling worker processes by sending a crafted form-encoded HTTP POST request containing deeply nested parameters. Because request parameters were parsed before routing and authentication, any POST endpoint could be used to trigger the condition, which could render the instance unresponsive. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.21 and was fixed in versions 3.20.3, 3.19.7, 3.18.10, and 3.17.16.
A path traversal vulnerability was identified in GitHub Enterprise Server that allowed an unauthenticated attacker to delete arbitrary files and directories on the instance, including the entire user storage directory containing Git LFS objects, release assets, attachments, and avatars. The X-GitHub-Request-Id request header was used without sanitization as a filesystem path segment for the upload buffer directory, so a traversal value pointed the buffer at an arbitrary path and the deferred cleanup routine recursively removed the traversed target. Exploitation required only network reachability to the instance and no authentication, and it worked even when private mode was enabled. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.21.4, 3.20.6, 3.19.10, 3.18.13 and 3.17.19. This vulnerability was reported via the GitHub Bug Bounty program.
Summary
A nil pointer dereference vulnerability in the GitHub MCP Server causes it to crash when receiving a malformed completion/complete request with missing or empty parameters. This allows any unauthenticated client to cause a complete denial of service.
Details
The CompletionsHandler function in pkg/github/server.go:198 accesses params.Ref without checking if it's nil first. When a client sends a completion/complete request with a missing ref field, the handler dereferences nil and the Go runtime panics.
The crash occurs before any authentication or token validation, so even requests with fake tokens can trigger it.
PoC
After completing the MCP initialization handshake, send either:
Empty params:
{"jsonrpc":"2.0","id":2,"method":"completion/complete","params":{}}
Missing ref field:
{"jsonrpc":"2.0","id":2,"method":"completion/complete","params":{"argument":{"name":"x","value":"y"}}}
Result:
panic: runtime error: invalid memory address or nil pointer dereference goroutine 42 [running]: github.com/github/github-mcp-server/pkg/github.NewMCPServer.CompletionsHandler.func1(...) pkg/github/server.go:198 +0x24
Impact
Any unauthenticated client that can send JSON-RPC messages to the server can crash it immediately. This is a complete denial of service - the panic is unrecoverable and kills the process.
Automated fuzzing with mcpsec found 108 crashes out of 925 test cases (11.7% crash rate).
Timeline
- Feb 21, 2026 - Initial report sent to opensource-security@github.com - Mar 03, 2026 - Follow-up email sent, no response - Mar 21, 2026 - Re-verified on v0.33.0, sent detailed report with PoC, no response - Apr 06, 2026 - GHSA filed after 44 days without acknowledgment
Suggested Fix
func (s Server) CompletionsHandler(ctx context.Context, params mcp.CompleteParams) (mcp.CompleteResult, error) { if params == nil || params.Ref == nil { return nil, fmt.Errorf("invalid request: missing ref parameter") } // ... rest of handler }
A missing authorization vulnerability was identified in GitHub Enterprise Server that allowed an authenticated user with write access to any repository to read metadata from private repositories they did not have access to, including private repository owners and names, branch names, commit SHAs, commit messages, and the pushing actor. The delegated bypass endpoint resolved a rule suite directly from an attacker-supplied, encoded identifier without verifying that the requesting user could read the rule suite's repository, and because these identifiers are sequential an attacker could enumerate them across the instance. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.17.18, 3.18.12, 3.19.9, 3.20.5, and 3.21.3. This vulnerability was reported via the GitHub Bug Bounty program.
A path traversal vulnerability was identified in GitHub Enterprise Server that allowed an attacker who had code execution inside the Dependabot updater container to write files to arbitrary repository paths, including GitHub Actions workflow files under .github/workflows/ as the path validation did not check the effective path which the attacker could control through the dependency file's directory and symlink target. If the repository used a pullrequesttarget workflow or had auto-merge enabled, an injected workflow could execute with access to the repository's GitHub Actions secrets. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.21.3, 3.20.5, 3.19.9, 3.18.12, 3.17.18.
A denial of service vulnerability was identified in GitHub Enterprise Server that allowed an authenticated user to cause service disruption by supplying a repository release notes configuration file containing deeply nested YAML. When release notes were generated, the configuration file was parsed without a nesting depth limit, causing excessive resource consumption that could render the instance unresponsive. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.17.18, 3.18.12, 3.19.9, 3.20.5, and 3.21.3. This vulnerability was reported via the GitHub Bug Bounty program.
GitHub CLI (gh) is GitHub’s official command line tool. From 2.10.0 through 2.95.0, connecting to a malicious Codespace with gh codespace jupyter can allow command execution because the command opens a JupyterLab URL supplied by a process inside the Codespace without validating that it is a loopback HTTP or HTTPS address, allowing a crafted vscode:// or vscode-insiders:// URL to be handed to VS Code. This issue is fixed in version 2.96.0.
An incorrect authorization vulnerability was identified in GitHub Enterprise Server that allowed a user-to-server token scoped to a GitHub App installation to perform certain write operations on public repositories outside the token's intended scope. This was possible because the authorization check only verified that the installation had read permissions on the target repository rather than verifying that the token's installation was explicitly granted access to that repository. An attacker who obtained a victim's user-to-server token could create issues, issue comments, commit comments, and private vulnerability reports on any public repository, appearing as the victim user with no indication of the app involvement. This vulnerability was fixed by adding a repository scope check for user-to-server tokens issued by global apps. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.21.2, 3.20.4, 3.19.8, 3.18.11, 3.17.17, 3.16.20. This vulnerability was reported via the GitHub Bug Bounty program.
A stored cross-site scripting vulnerability was identified in GitHub Enterprise Server that allowed an authenticated attacker to execute arbitrary JavaScript in another user's browser by injecting a crafted payload into the title of a Discussion in the Q&A category. The AnsweredQuestionStructuredDataComponent did not escape user-controlled Discussion titles before embedding them in a <script type="application/ld+json"> block, allowing the title to break out of the script context. The injection was escalated to a full cross-site scripting attack on GitHub Enterprise Server by leveraging JSONP callback support in the REST API to bypass the Content Security Policy. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.21 and was fixed in versions 3.20.4, 3.19.8, 3.18.11, 3.17.17, 3.16.20. This vulnerability was reported via the GitHub Bug Bounty program.
A missing authorization vulnerability was identified in GitHub Enterprise Server that allowed an authenticated user to read source code from private repositories they did not have access to. The Copilot pull request description diff summary endpoint accepted a cross-repository comparison range and rendered the resulting diff without verifying that the requesting user was authorized to view the target repository. Exploitation required an authenticated account on the instance with read access to at least one repository to use as the comparison base. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.21 and was fixed in versions 3.17.17, 3.18.11, 3.19.8, and 3.20.4. This vulnerability was reported via the GitHub Bug Bounty program.
A UI misrepresentation vulnerability was identified in GitHub Enterprise Server that allowed an OAuth application to gain unintended access to an organization's runner management. An attacker could exploit this by creating an OAuth application requesting the managerunners:org scope and directing a victim user to authorize it, as the scope was not displayed on the authorization consent screen. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.22 and was fixed in versions 3.21.2, 3.20.4, 3.19.8, 3.18.11, 3.17.17, 3.16.20. This vulnerability was reported via the GitHub Bug Bounty program.
GitHub Copilot 1.372.0 allows filesystem access outside of a workspace folder (without user approval) via a file-handler URI parameter to fetchwebpage. Therefore, exfiltration could occur if there is indirect prompt injection.
Summary
GitHub CLI incorrectly includes an authorization header in API requests to TUF repository mirrors via gh attestation, gh release verify, and gh release verify-asset commands.
Affected users:
- Authenticated github.com users who previously ran gh attestation commands, gh release verify, or gh release verify-asset: the github.com token was included in requests to tuf-repo.github.com, a GitHub Pages domain that is not a GitHub API endpoint. All authentication types are affected. - Users with GHENTERPRISETOKEN or GITHUBENTERPRISETOKEN set who previously ran gh attestation commands, gh release verify, or gh release verify-asset: the enterprise token was included in requests to external hosts tuf-repo-cdn.sigstore.dev and tmaproduction.blob.core.windows.net. These hosts are not operated by GitHub.
Details
The CLI uses a shared HTTP client with an authentication layer that automatically attaches tokens to outgoing requests. This layer lacks accurate host detection and can incorrectly attribute the target host, providing it with a token it should never receive.
Specifically, the host normalization logic collapses any .github.com subdomain to github.com, so a request to tuf-repo.github.com (a GitHub Pages site, not a GitHub API endpoint) is treated as a request to github.com and receives the user's github.com token. For hosts that don't match github.com or a known GHES instance at all, the resolver falls back to GHENTERPRISETOKEN if set.
The gh attestation, gh release verify and gh release verify-asset commands fetch data from several external hosts as part of their normal operation (TUF metadata from tuf-repo.github.com and tuf-repo-cdn.sigstore.dev, artifact bundles from Azure Blob Storage). Because these requests go through the same authenticated HTTP client, the token is sent to all of them.
Impact
Tokens were transmitted in HTTP headers to the listed hosts during normal gh attestation, gh release verify, and gh release verify-asset operations. There is no evidence that tokens were logged, retained, or accessed by unauthorized parties. If a token were captured, it would grant the same access as the token holder, potentially including private repositories, organization resources, or enterprise administration depending on token type and permissions.
Remediation and mitigation
1. Revoke authentication tokens used with the GitHub CLI: - Personal access tokens - GitHub CLI OAuth app 2. Upgrade gh to 2.93.0. 3. Review personal security logs and any relevant audit logs for actions associated with personal or enterprise accounts.