github-mcp-server
- Type
- MCP server
- Scanned
- Oct 29, 2026
- Version
- f2a07cd13243
- Files read
- 594
The GitHub MCP Server connects AI assistants to GitHub so they can read and manage repositories, issues, pull requests, workflows, and security alerts. The biggest risk is that malicious instructions hidden in untrusted GitHub content could trick the AI into exposing private data, making unauthorized changes, or using unescaped tool inputs to call unintended GitHub API endpoints with your credentials.
What it can reach
- Network
- Connects to GitHub API, raw content, upload, and OAuth endpoints (on github.com or GitHub Enterprise), and can listen on local ports for HTTP server mode or OAuth login callbacks.
- Secrets
- Reads GitHub Personal Access Tokens, OAuth credentials, GitHub App private keys, and encryption keys from environment variables, files, or HTTP headers.
- Files
- Reads optional local configuration files and GitHub App private key files, and writes optional log and translation export files.
- Browser
- Opens the system default web browser on your computer during interactive OAuth login.
Findings
-
HighREST API path traversal via unescaped
ownerandrepotool argumentsMultiple tool handlers—including
get_code_quality_findinginpkg/github/code_quality.go,find_duplicateinpkg/github/find_duplicate.go, and issue handlers inpkg/github/issues.goandpkg/github/issues_granular.go—interpolateownerandrepodirectly intofmt.Sprintf("repos/%s/%s/...", ...)before callingclient.NewRequest. Becausego-githubresolves the path withBaseURL.Parse, an attacker supplying..and#via prompt injection (for example,repo = "../../repos/org/private-repo/secret-scanning/alerts/1#") can traverse to arbitrary GitHub REST API endpoints using the user's token. Inget_code_quality_finding, any JSON object returned by the target endpoint is marshaled back to the caller, bypassing--tools/--toolsetsrestrictions, dynamic OAuth scope challenges, andMcp-Param-*proxy routing.Fix: Validate that
ownerandrepodo not contain path separators,.., query, or fragment characters, and escape path segments withurl.PathEscape(as done inpkg/github/rulesets.goandpkg/github/custom_properties.go). -
MediumUnbounded and uncancellable HTTP log download in
downloadLogContentWhen
get_job_logsis called withreturn_content=true,downloadLogContentdownloads the job log URL usinghttp.Get(logURL)onhttp.DefaultClient. It does not bind the request to the caller'sctx, sets no HTTP timeout, and streams the entire response body untilEOF(only keeping a ring buffer of lines in memory). A stalled endpoint or multi-gigabyte workflow log can tie up server resources indefinitely even after the MCP request is cancelled.Fix: Create the request with
http.NewRequestWithContext(ctx, http.MethodGet, logURL, nil), use anhttp.Clientwith a reasonable timeout, and cap the total number of bytes read from the response body. -
LowHTTP server mode binds to all network interfaces by default
cmd/github-mcp-server/main.go:272
When running
github-mcp-server http, the--listen-hostflag defaults to an empty string, which causesresolveListenAddressinpkg/http/server.goto bind to:8082on all network interfaces (0.0.0.0/::). Although requests require a bearer token in theAuthorizationheader, binding to all interfaces by default unnecessarily exposes the local HTTP server to the network.Fix: Default
--listen-hostto127.0.0.1and require an explicit flag (such as--listen-host 0.0.0.0) to bind to all interfaces. -
LowMCP App UI
openLinkbypasses host denial and does not validate URL schemesWhen an MCP App UI component calls
openLink(url)and the MCP host rejects the request (result?.isError, for example due to a blocked domain or user cancellation),openLinkignores the host's decision and opens the URL anyway viawindow.open. In addition, untrusted profile links such asd.bloginui/src/apps/get-me/App.tsxare rendered into<Link href={d.blog}>and passed toopenLinkwithout verifying that the URL useshttp:orhttps:.Fix: Validate that external URLs use
https:orhttp:before rendering or opening them, and do not fall back towindow.openwhenapp.openLinkreturns an explicit host denial. -
LowCommand injection when parsing untrusted logs in developer script
script/prettyprint-logThe developer utility
script/prettyprint-logextracts JSON payloads from log files and interpolates them into a double-quotedecho -e "..."command that is piped tobash. If a log file contains untrusted GitHub issue or PR text with shell command substitutions ($(...)or backticks), running this script on the log file will execute arbitrary shell commands.Fix: Avoid piping log content into
bash; usejq -rorprintf '%b'without invoking a subshell to unescape the JSON string. -
LowOverly permissive Content Security Policy in MCP App UI templates
ui/src/apps/get-me/index.html:6
The get-me MCP App UI defines a Content Security Policy that allows 'unsafe-eval' and unrestricted outbound connections via 'connect-src *', while the other UI entrypoints (issue-write, pr-edit, and pr-write) omit a Content Security Policy altogether. Because these UI views render untrusted GitHub content, permitting eval and arbitrary network connections weakens defense-in-depth if a rendering flaw is introduced.
Fix: Remove 'unsafe-eval' and restrict 'connect-src' to 'none' (since MCP Apps communicate with the host over postMessage), and apply the policy across all UI app index.html templates.