Back to skill

Security audit

Read GitHub

Security checks for vulnerabilities and agentic risk

Overview

The skill is meant to read GitHub repositories, but it runs unpinned npm code and exposes broader remote MCP and URL-fetching behavior than its core purpose requires.

Review before installing. Use this only in a restricted environment where npm package execution and outbound network access are acceptable. Avoid passing secrets in repository names, search queries, tool arguments, or fetched URLs, and prefer a version that pins `mcp-remote`, validates GitHub/gitmcp.io inputs, removes or allowlists direct MCP tool calls, and limits external URL fetching.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Error
Location
scripts/gitmcp.py:56
Finding

Unpinned npm Package Is Automatically Retrieved and Executed

Content
View full analysis

Vulnerability Details

File Location: scripts/gitmcp.py, lines 56-66 and 90-100
Vulnerability Type: Unpinned third-party package execution
Risk Level: High

Vulnerable Code

python
proc = subprocess.Popen(
    ["npx", "-y", "mcp-remote", mcp_url],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True,
    bufsize=1
)

The same invocation is used by both list_tools() and call_tool().

Technical Analysis

Every supported operation launches mcp-remote through npx using the -y option. The package has no exact version, lockfile, integrity hash, or locally reviewed installation associated with it. Consequently, npm may resolve, download, and execute a package version that was not present when this Skill was audited.

The -y option suppresses the interactive installation confirmation. This turns normal use of the Skill into an automatic third-party code execution path. If the npm package, one of its dependencies, or the relevant registry resolution is compromised, malicious installation scripts or runtime code can execute under the account running the Skill.

Attack Path

  1. An attacker compromises the published mcp-remote package, its maintainer account, or a transitive dependency.
  2. A malicious package version is made available through npm resolution.
  3. A user or agent runs any documented command, such as list-tools, fetch-docs, or search-code.
  4. The script invokes npx -y mcp-remote without an exact version constraint.
  5. npx resolves and may automatically download the compromised package.
  6. The package executes locally with the privileges and environment of the user running the Skill.

Impact Assessment

Successful supply-chain exploitation can result in arbitrary code execution with the current user's privileges. Depending on the execution environment, the malicious package could access readable project ...[truncated 262 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add mcp-remote as a declared project dependency pinned to a reviewed exact version.
  2. Commit the appropriate lockfile and use deterministic installation, such as npm ci.
  3. Verify package integrity through lockfile integrity metadata and trusted registry configuration.
  4. Install dependencies during a controlled deployment step rather than during each Skill invocation.
  5. Invoke the locally installed, pinned executable instead of using npx -y.
  6. Audit the selected package version and its transitive dependencies before deployment.
  7. Run the bridge in a restricted environment with minimal filesystem, environment-variable, credential, and network access.
  8. Establish an explicit dependency-update review process so package upgrades cannot silently alter executed code.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gitmcp.py:16
Finding

Unvalidated Repository Input Permits Connections to Arbitrary MCP Servers

Content
View full analysis

Vulnerability Details

File Location: scripts/gitmcp.py, lines 16-25 and 175-176
Vulnerability Type: Missing URL scheme and hostname validation
Risk Level: Medium

Vulnerable Code

python
def convert_github_to_gitmcp(url_or_path: str) -> str:
    """Convert a GitHub URL or owner/repo path to gitmcp.io URL."""
    # Handle full GitHub URLs
    if "github.com" in url_or_path:
        return url_or_path.replace("github.com", "gitmcp.io")

    # Handle owner/repo format
    if "/" in url_or_path and not url_or_path.startswith("http"):
        return f"https://gitmcp.io/{url_or_path}"

    return url_or_path

The resulting value is passed directly to the MCP client:

python
# Convert repo to gitmcp URL
mcp_url = convert_github_to_gitmcp(args.repo)
repo_name = get_repo_name_from_url(mcp_url)

It is subsequently used in both MCP process invocations:

python
["npx", "-y", "mcp-remote", mcp_url]

Technical Analysis

The Skill is documented as a client for GitHub repositories through gitmcp.io, but the conversion function does not enforce that scope. An input beginning with http that does not contain github.com is returned unchanged. There is no URL parsing, exact hostname allowlist, HTTPS requirement, port restriction, or rejection of embedded credentials.

As a result, a caller can direct the MCP bridge to an attacker-controlled endpoint rather than gitmcp.io. That endpoint controls MCP initialization responses, tool metadata, and tool-call responses. Search queries and direct-call arguments sent through the client are also disclosed to the selected server.

The use of substring replacement for github.com is additionally weaker than validating a parsed hostname. A string containing that substring is transformed even when github.com is not the actual network host.

Attack Path

  1. An attacker supplies or recommends a crafted repository argument that ...[truncated 1209 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse input with a standard URL parser rather than using substring replacement.
  2. For full URLs, require the https scheme and the exact hostname gitmcp.io.
  3. Reject embedded usernames or passwords, unexpected ports, fragments, malformed paths, and unsupported schemes.
  4. For GitHub URLs, require the exact hostname github.com, extract only a validated owner and repository pair, and construct the GitMCP URL from those components.
  5. Validate shorthand repository identifiers against a strict owner/repository pattern and reject additional path traversal or URL syntax.
  6. Remove arbitrary endpoint support unless it is an explicit requirement. If it is required, place it behind a clearly named opt-in option and display a trust warning.
  7. Avoid sending secrets or confidential data in search queries and direct MCP arguments.
  8. Treat all remote MCP output as untrusted content and ensure downstream agents do not interpret it as authoritative instructions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

MCP Config Access

High
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · scripts/gitmcp.py (reported line 155)May include surrounding context.

python
subparsers = parser.add_subparsers(dest="command", help="Command to run")

    # list-tools command
    list_parser = subparsers.add_parser("list-tools", help="List available MCP tools for a repo")
    list_parser.add_argument("repo", help="GitHub repo (owner/repo or full URL)")

    # fetch-docs command

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

An arbitrary-tool execution path via MCP is a real security concern because it delegates trust to whatever tools the remote server exposes at runtime. In the context of a supposedly read-only GitHub skill, that mismatch makes the capability more dangerous: users and orchestrators may grant it permissions under a narrower threat model than the code actually implements.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill invokes a shell-accessed script (python3 scripts/gitmcp.py ...) but does not declare any tool scope, permissions, or allowed-tools constraints. This creates an under-specified execution boundary: an agent may grant broader shell access than users expect, increasing the risk of unintended command execution or misuse if arguments are influenced by untrusted input.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to contact third-party infrastructure (gitmcp.io) and also fetch arbitrary external URLs referenced in repository documentation, but the description does not warn users about these outbound requests. This can expose user queries, repository targets, or fetched references to external services and may surprise users who assume local-only analysis.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/gitmcp.py (reported line 62)May include surrounding context.

python
def list_tools(mcp_url: str) -> dict:
    """Connect to MCP server and list available tools."""
    proc = subprocess.Popen(
        ["npx", "-y", "mcp-remote", mcp_url],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/gitmcp.py (reported line 93)May include surrounding context.

python
def list_tools(mcp_url: str) -> dict:
    """Connect to MCP server and list available tools."""
    proc = subprocess.Popen(
        ["npx", "-y", "mcp-remote", mcp_url],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

The epilog and corresponding implementation advertise a generic ability to call any tool directly, which is unrestricted tool access inconsistent with the skill's declared narrow purpose. In agent ecosystems, that kind of hidden generality is dangerous because it enables privilege expansion through whatever actions the remote MCP server chooses to expose.

Content

Scanner excerpt · scripts/gitmcp.py (reported line 147)May include surrounding context.

python
# Fetch a URL mentioned in docs
  %(prog)s fetch-url karpathy/llm-council "https://example.com/doc"

  # Call any tool directly
  %(prog)s call karpathy/llm-council fetch_llm_council_documentation '{}'
"""
    )

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill is presented as a GitHub repository reader, but fetch-url invokes fetch_generic_url_content with an arbitrary URL supplied by the user. That creates capability drift: the tool can access external web resources beyond GitHub documentation, which increases data-exfiltration, unexpected network access, and policy-bypass risk in contexts where only repository reading was expected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code performs remote repository lookups and arbitrary URL fetching without any user-facing warning, consent step, or clear disclosure that data will be sent to gitmcp.io and potentially other external sites. This is risky in agent environments because prompts, URLs, and repository targets may contain sensitive information, and users may reasonably assume the skill is limited to local parsing or GitHub-only reads.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The direct call command allows the operator to invoke any MCP tool name exposed by the remote server, not just the documented repository-reading functions. In a skill advertised as a narrow GitHub-reading interface, this creates an unexpectedly broad remote capability surface that could expose privileged tools, hidden actions, or future server-side features the client did not intend to permit.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.