Back to skill

Security audit

GitHub Latest Hot Repo Explorer

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it secretly reads a GitHub token from a home-directory credential file despite saying it will not read `.env` files.

Review before installing. The skill searches GitHub and records shown repositories locally, which matches its purpose, but it may silently use a GitHub token from `~/.openclaw/.env` even though the docs say it will not read `.env` files. Install only if you are comfortable with that credential use, or require the publisher to remove the fallback and rely only on an explicitly provided `GITHUB_TOKEN`. Treat fetched README content as untrusted third-party text.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/fetch_repo.py:33
Finding

Undisclosed Access to a User Credential File

Content
View full analysis

Vulnerability Details

File Location: scripts/fetch_repo.py, lines 33–48 and 61–64
Vulnerability Type: Undisclosed credential-file access
Risk Level: Medium

Vulnerable Code

python
def load_token() -> str:
    """Prefer the environment variable; otherwise read ~/.openclaw/.env."""
    token = os.environ.get("GITHUB_TOKEN", "")
    if token:
        return token
    env_file = os.path.expanduser("~/.openclaw/.env")
    try:
        with open(env_file, "r", encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if line.startswith("GITHUB_TOKEN="):
                    value = line.split("=", 1)[1].strip().strip('"').strip("'")
                    if value:
                        return value
    except OSError:
        pass
    return ""

The retrieved token is subsequently attached to network requests:

python
if token:
    request_headers["Authorization"] = f"Bearer {token}"
if headers:
    request_headers.update(headers)
try:
    with urllib.request.urlopen(
        urllib.request.Request(url, headers=request_headers),
        timeout=30
    ) as response:

Technical Analysis

When GITHUB_TOKEN is unavailable in the process environment, load_token() silently falls back to reading ~/.openclaw/.env. It parses that file for a GITHUB_TOKEN entry and returns the credential without requiring explicit opt-in or notifying the user that a credential file was accessed.

This behavior conflicts with the documented authorization model:

  • SKILL.md, lines 17–20, states that the Skill reads only the system environment variable and does not read or create .env files.
  • references/README.md, lines 1–3, likewise states that the script only reads GITHUB_TOKEN from the environment and does not read an .env file.

The retrieved credential is used as a bearer token for requests to the fixed GitHub API endpoints. The inspected code does not send the token to an unrelated recipie ...[truncated 1570 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the implicit ~/.openclaw/.env fallback and obtain the token exclusively from os.environ.get("GITHUB_TOKEN"), matching the documented behavior.
  2. If credential-file support is necessary, require an explicit command-line option such as --token-file and disclose the exact path before reading it.
  3. Do not default to a shared application credential store. Restrict any supported token file to a user-selected path and validate that it is a regular file owned by the current user with restrictive permissions.
  4. Keep credentials out of output, errors, history records, and generated reports.
  5. Add tests verifying that the script does not access ~/.openclaw/.env during normal execution.
  6. Update SKILL.md and references/README.md if the intended credential-loading behavior changes, ensuring the implementation and authorization documentation remain consistent.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The code is designed to access credentials for GitHub authentication, and the surrounding comment explicitly justifies a fallback because normal execution snapshots filter token-like environment variables. That indicates an intentional attempt to recover secrets from local storage despite platform controls, which is risky in a low-privilege repository-exploration skill.

Content

Scanner excerpt · scripts/fetch_repo.py (reported line 33)May include surrounding context.

python
def load_token() -> str:
    """优先读环境变量;读不到再从 ~/.openclaw/.env 读(OpenClaw exec 快照会过滤 token 类环境变量,故需文件回退)。"""
    token = os.environ.get("GITHUB_TOKEN", "")
    if token:
        return token

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

Reading ~/.openclaw/.env directly is a credential-harvesting pattern because it reaches into a user-specific secret store unrelated to the minimal task of ranking repositories. Even if only a GitHub token is sought, this normalizes bypassing least-privilege boundaries and can expose user secrets to untrusted skill code.

Content

Scanner excerpt · scripts/fetch_repo.py (reported line 37)May include surrounding context.

python
token = os.environ.get("GITHUB_TOKEN", "")
    if token:
        return token
    env_file = os.path.expanduser("~/.openclaw/.env")
    try:
        with open(env_file, "r", encoding="utf-8") as f:
            for line in f:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes capabilities that involve reading environment variables, accessing local history files, writing state, and making network requests to GitHub, but it does not declare any explicit tool scope or permissions boundaries. In agent environments, missing scope declarations can lead to over-broad execution privileges, making it easier for the skill to access sensitive data or perform unintended file/network operations if invoked in a more privileged runtime.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description and main instructions are written as an unconditional Chinese-language experience, indicating the skill is intended to operate in Chinese without mentioning any user-selectable language or locale option. This is a natural-language policy concern because it imposes a specific language without documented opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file is a markdown template and all section headings and instructions are written in Chinese, effectively requiring responses in a specific language. The policy allows locale constraints only when the skill offers user choice or clearly documents a justified region-specific requirement, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring is written entirely in Chinese and frames the skill's behavior in that locale, with no indication that users may choose another language. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is documented and justified.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fetch_repo.py (reported line 15)May include surrounding context.

python
from pathlib import Path
from typing import Optional, Union

SEARCH_URL = "https://api.github.com/search/repositories"
README_URL_TMPL = "https://api.github.com/repos/{owner}/{repo}/readme"
PER_PAGE = 100
README_MAX_CHARS = 8000

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

This endpoint is used to retrieve and print README content from arbitrary repositories, which goes beyond simple repository selection and imports untrusted remote text into the skill output. In an agent setting, that content can contain adversarial instructions or harmful prompt-injection material, making the transmission more dangerous than the search API alone.

Content

Scanner excerpt · scripts/fetch_repo.py (reported line 16)May include surrounding context.

python
from typing import Optional, Union

SEARCH_URL = "https://api.github.com/search/repositories"
README_URL_TMPL = "https://api.github.com/repos/{owner}/{repo}/readme"
PER_PAGE = 100
README_MAX_CHARS = 8000
WINDOW_STEPS = [1, 2, 3, 6, 12, 24]

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill reads a GitHub token not only from the environment but also from a fallback file in the user's home directory specifically to bypass token filtering in the execution environment. That is a credential-access behavior beyond the stated repository-exploration purpose and increases the chance that sensitive credentials are used or exposed unexpectedly during untrusted skill execution.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill fetches and prints up to 8000 characters of arbitrary third-party README content, which exceeds the manifest's narrow purpose of selecting the top-star hot repository. Pulling and surfacing untrusted remote content expands the attack surface for prompt injection, misleading instructions, or sensitive-data mixing in downstream agent workflows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

These print statements present the repository summary and follow-up instructions only in Chinese, which enforces a specific language for interaction. The file does not offer an alternate locale or explain why Chinese-only output is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.