Back to skill

Security audit

Github Explorer

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says: searches and analyzes GitHub repositories, with disclosed GitHub API use and local caching.

Use a fine-grained, read-only GitHub token with the smallest repository scope needed. Use --no-cache when analyzing private or sensitive repositories, and run cache clear if cached results should be removed.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/github_explorer.py:217
Finding

Authenticated GitHub repository data may be cached with insufficiently restrictive permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/github_explorer.py, lines 217-230
Vulnerability Type: Insecure persistent storage of potentially sensitive repository data
Risk Level: Medium

Vulnerable Code

python
def _cache_set(*parts):
    result = parts[-1]
    key_parts = parts[:-1]
    key = _cache_key(*key_parts)
    try:
        os.makedirs(CACHE_DIR, exist_ok=True)
        path = os.path.join(CACHE_DIR, f"{key}.json")
        with open(path, "w") as f:
            json.dump({"_t": time.time(), "_r": result}, f)
    except OSError:
        pass

The cached data can originate from authenticated repository and README requests:

python
def _headers():
    headers = {
        "Accept": "application/vnd.github+json",
        "User-Agent": "github-explorer-skill",
        "X-GitHub-Api-Version": "2022-11-28",
    }
    token = os.environ.get("GITHUB_TOKEN", "")
    if token:
        headers["Authorization"] = f"Bearer {token}"
    return headers
python
detail = _api_get(f"/repos/{repo}")
readme = _api_get(f"/repos/{repo}/readme")
...
_cache_set("analyze", repo, readme_full, result)

Technical Analysis

The Skill optionally authenticates GitHub API requests using GITHUB_TOKEN. If that token grants access to private repositories, GitHub can return private repository metadata and README content. The analyze command then stores this response persistently in ~/.cache/github-explorer/.

The cache directory is created with os.makedirs() without an explicit 0700 mode, and cache files are created with open(path, "w") without an explicit 0600 mode. Their effective permissions therefore depend on the process umask and the permissions of any pre-existing cache directory. In an environment with a permissive umask, shared user context, exposed home directory, or improperly configured backup process, another local principal or process may be ...[truncated 2050 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create and verify the cache directory with owner-only permissions:

    python
    os.makedirs(CACHE_DIR, mode=0o700, exist_ok=True)
    os.chmod(CACHE_DIR, 0o700)
    

    Before using it, verify that the path is a real directory owned by the current user and is not a symbolic link.

  2. Create cache files with explicit 0600 permissions rather than relying on the process umask. Use os.open() with restrictive flags and wrap the descriptor with os.fdopen().

  3. Write through a securely created temporary file in the same directory and atomically publish it with os.replace(). Reject or avoid symbolic links where the operating system supports O_NOFOLLOW.

  4. Disable caching by default for authenticated requests, or require explicit consent before caching responses obtained with GITHUB_TOKEN. At minimum, provide a dedicated option that prevents caching potentially private data.

  5. Clearly document that authenticated requests may return and persist private repository information. The existing general cache notice should explicitly mention private metadata and README content.

  6. Recommend fine-grained, read-only GitHub tokens restricted to only the required repositories. Avoid recommending broad classic-token scopes such as unrestricted repo access.

  7. Preserve the existing --no-cache option and advise users to use it whenever analyzing sensitive or private repositories.

Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 123)May include surrounding context.

export GITHUB_TOKEN="ghp_你的token"

text

不配置也能用(限流更严格)。Token 在 GitHub → Settings → Developer settings → Personal access tokens 生成,只需 `public_repo` 只读权限。

---

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill invokes local Python code, uses network access to GitHub, reads environment variables, and persists data to a cache path, but it does not declare a clear tool scope or allowed-tools boundary for those capabilities. That mismatch increases the attack surface because an agent may execute broader file, env, or network actions than reviewers and users expect, reducing transparency and policy enforcement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The user-facing documentation and help strings are presented in Chinese throughout, and the skill behavior is oriented around Chinese-to-English query mapping without any opt-in or alternate locale path. This can violate language/locale policy when a skill imposes a specific language experience rather than offering a user choice or clearly documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code stores search and analyze results under ~/.cache/github-explorer/, and analyze results can include README content from repositories. While the module docstring mentions caching, it does not clearly warn users that fetched content is written to disk locally by default, which is a user-visible data handling behavior relevant to privacy and disk state.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.