Back to skill

Security audit

GitHub Fetch

Security checks for vulnerabilities and agentic risk

Overview

This GitHub download helper is mostly purpose-aligned, but it can route downloads through third-party mirrors and install unverified archives or binaries into persistent locations.

Install only if you are comfortable with a helper that may send full GitHub URLs to third-party mirrors and can extract or install downloaded binaries. Prefer direct GitHub downloads, provide a trusted SHA-256 or signature before extraction or installation, avoid signed/private URLs with proxies, and avoid sudo or /usr/local/bin placement unless you have independently verified the artifact.

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 (3)

T08 · Insecure Dependencies

Error
Location
scripts/github_fetch.py:25
Finding

Unverified content from third-party mirrors can be extracted and installed

Content
View full analysis
tuple[str | None, str | None, float]: """Direct connection first; probe proxies if it is unusable.""" ok, speed, code = probe_speed(gh_url, timeout) if ok and speed >= min_speed: return gh_url, "direct", speed print(f"[i] Direct connection unavailable; probing proxy mirrors...") best_url, best_name, best_speed = None, None, 0.0 for p in proxies: proxied = f"{p}/{gh_url}" ok, sp, code = probe_speed(proxied, timeout) if ok and sp > best_speed: best_url, best_name, best_speed = proxied, p, sp return best_url, best_name, best_speed ``` The original source uses localized display strings, but the control flow above is reproduced without alteration. ```python if not download(best_url, dest, timeout=args.timeout): sys.exit(1) # Verification if not verify(dest, args.sha256, args.verify_url): print("[x] Verification failed; file deleted") dest.unlink(missing_ok=True) sys.exit(1) # Extraction extracted = None if args.extract: extracted = extract(dest, out_dir) # Installation if args.install: src = extracted or dest install(src, Path(args.install)) ``` The quick-start documentation demonstrates extraction and installation without supplying a checksum: ```bash python3 scripts/github_fetch.py "https://github.com/BtbN/FF ...[truncated 2326 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/github_fetch.py:152
Finding

Archive extraction does not validate paths, links, file types, or extractor success

Content
View full analysis
Path | None: """Extract and return the top-level directory, if one exists.""" out_dir.mkdir(parents=True, exist_ok=True) name = dest.name.lower() try: if name.endswith((".tar.xz", ".tar.gz", ".tar.bz2", ".tar", ".tgz", ".tar.zst")): _run(["tar", "xf", str(dest), "-C", str(out_dir)], timeout=600) elif name.endswith(".zip"): _run(["unzip", "-q", "-o", str(dest), "-d", str(out_dir)], timeout=600) else: print("[i] Non-archive file; skipping extraction") return None except Exception as e: print(f"[x] Extraction failed: {e}") return None subs = [p for p in out_dir.iterdir() if p.is_dir() and not p.name.startswith(".")] print(f"[✓] Extracted to {out_dir}") return subs[0] if len(subs) == 1 else None ``` The original source uses localized display strings, but the extraction operations and control flow above are reproduced without alteration. ### Technical Analysis The archive is passed directly to the platform `tar` or `unzip` utility. Before extraction, the script does not inspect archive members for: - Absolute paths - Parent-directory traversal components such as `../` - Symbolic or hard links whose targets escape the output directory - Device nodes, FIFOs, or other special files - Unexpected permissions or ownership metadata - Collisions with existing files in the output directory The protection provided by command-line extraction tools varies by utility and platform. Relying solely on their defaults is not an adequate application-level security boundary, particularly for archives downloaded through third-party mirrors. The `_run()` result is also discarded. A nonzero extractor exit status therefore does not cau ...[truncated 1674 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/github_fetch.py:77
Finding

Sensitive URL components can be disclosed to multiple proxy operators and process logs

Content
View full analysis
tuple[str | None, str | None, float]: ok, speed, code = probe_speed(gh_url, timeout) if ok and speed >= min_speed: return gh_url, "direct", speed best_url, best_name, best_speed = None, None, 0.0 for p in proxies: proxied = f"{p}/{gh_url}" ok, sp, code = probe_speed(proxied, timeout) if ok and sp > best_speed: best_url, best_name, best_speed = proxied, p, sp return best_url, best_name, best_speed ``` ```python def download(url: str, dest: Path, min_speed_hint: bool = True, timeout: int = 600) -> bool: cmd = ["curl", "-sL", "-C", "-", "-o", str(dest), "--retry", "3", "--retry-delay", "2", "-m", str(timeout), url] t0 = time.time() r = _run(cmd, timeout=timeout + 30) dt = time.time() - t0 if r.returncode != 0 or not dest.exists() or dest.stat().st_size == 0: print(f"[x] Download failed rc={r.returncode}: {url}") return False print(f"[✓] Download complete; source url={url}") return True ``` The original source includes additional localized status details, but the URL handling and disclosure points above are reproduced without alteration. ### Technical Analysis The script accepts a URL without enforcing a GitHub-owned hostname allowlist. If direct access is considered too slow, it constructs a proxy URL by appending the complete original URL to each configured proxy prefix. Consequently, URL query strings, embedded user information, signed download parameters, or token-like values are sent to every mirror tested during proxy selection. The selected full URL is also printed ...[truncated 1498 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (22)

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The description instructs the agent to use this skill whenever the user mentions GitHub downloads, cloning, binaries, or stalled fetches, even without explicit request for mirror/proxy help. That overly broad trigger can route many benign requests into a high-privilege workflow that probes third-party mirrors, downloads binaries, extracts archives, and may install artifacts, expanding attack surface and increasing the risk of unneeded external transfers or unsafe execution paths.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This duplicate finding points to the same unsafe behavior: interpolating an attacker-influenced filename into a shell command example without quoting. In a tool that downloads from arbitrary URLs and mirrors, this becomes especially risky because remote-controlled filenames can socially engineer operators into executing harmful pasted commands.

Content

Scanner excerpt · scripts/github_fetch.py (reported line 302)May include surrounding context.

python
print(f"[✓] 完成,输出: {dest}")
    print("    磁盘占用清理提示: 确认无误后可删除压缩包 "
          f"`rm {dest}`({dest.stat().st_size/1048576:.0f}MB)")


if __name__ == "__main__":

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This duplicate finding points to the same unsafe behavior: interpolating an attacker-influenced filename into a shell command example without quoting. In a tool that downloads from arbitrary URLs and mirrors, this becomes especially risky because remote-controlled filenames can socially engineer operators into executing harmful pasted commands.

Content

Scanner excerpt · scripts/github_fetch.py (reported line 302)May include surrounding context.

python
print(f"[✓] 完成,输出: {dest}")
    print("    磁盘占用清理提示: 确认无误后可删除压缩包 "
          f"`rm {dest}`({dest.stat().st_size/1048576:.0f}MB)")


if __name__ == "__main__":

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares broad operational behavior involving shell execution, file writes, environment-variable-controlled proxy selection, extraction, and installation, but does not define any explicit tool or permission scope. In an agent environment, this increases the chance the skill will be invoked with more authority than necessary and perform filesystem or command actions without clear containment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill advertises post-download actions including verification, extraction, and installation, but does not prominently require the agent to warn the user before making persistent system changes. In context, this is risky because the skill handles binaries from external sources and could cause filesystem modifications or package-style installation as part of what appears to be a simple download task.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The main instructional content is presented in Chinese, while there is no statement that language can be adapted to user preference. This creates a locale/language constraint without opt-in, which fits the policy category for forced language behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

These instructions recommend system-level installation with sudo and PATH-affecting symlinks without a prominent safety checkpoint. Because the skill is meant to fetch GitHub artifacts and may use fallback mirrors, combining external binary retrieval with privileged installation materially increases the risk of system compromise or persistence if a downloaded artifact is malicious or tampered with.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
95% confidence
Finding

Using sudo to create installation directories for downloaded artifacts elevates a network retrieval task into privileged system modification. In this skill, that is especially dangerous because the binaries originate from GitHub or third-party mirrors, so a compromised or substituted artifact could gain trusted placement on the host.

Content

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

6. 安装

bash
sudo mkdir -p /opt/<app>
sudo cp -r <解压目录>/bin /opt/<app>/
sudo ln -sf /opt/<app>/bin/ffmpeg /usr/local/bin/ffmpeg-gpu   # 建符号链接到 PATH

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The documented workflow establishes durable command availability through copied binaries and PATH-linked symlinks, which is a form of session persistence. Given that the skill may fetch via third-party proxies and then install the result, persistence amplifies the consequences of any integrity failure or malicious artifact.

Content

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

6. 安装

bash
sudo mkdir -p /opt/<app>
sudo cp -r <解压目录>/bin /opt/<app>/
sudo ln -sf /opt/<app>/bin/ffmpeg /usr/local/bin/ffmpeg-gpu   # 建符号链接到 PATH

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The documented workflow establishes durable command availability through copied binaries and PATH-linked symlinks, which is a form of session persistence. Given that the skill may fetch via third-party proxies and then install the result, persistence amplifies the consequences of any integrity failure or malicious artifact.

Content

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

6. 安装

bash
sudo mkdir -p /opt/<app>
sudo cp -r <解压目录>/bin /opt/<app>/
sudo ln -sf /opt/<app>/bin/ffmpeg /usr/local/bin/ffmpeg-gpu   # 建符号链接到 PATH

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
95% confidence
Finding

Copying downloaded binaries into /opt with sudo creates a trusted, persistent system location for externally sourced code. Without strong provenance checks and explicit authorization, this can facilitate installation of malicious or trojaned binaries with elevated trust.

Content

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

bash
sudo mkdir -p /opt/<app>
sudo cp -r <解压目录>/bin /opt/<app>/
sudo ln -sf /opt/<app>/bin/ffmpeg /usr/local/bin/ffmpeg-gpu   # 建符号链接到 PATH
  • 系统级安装用 /opt/ + /usr/local/bin/ 链接;用户级安装放 ~/.local/bin/

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
97% confidence
Finding

Creating a symlink in /usr/local/bin with sudo exposes the downloaded executable on the user's PATH, making it easy to invoke as a trusted command and establishing persistence beyond the current session. In the context of mirrored downloads and binary installation, this materially increases the blast radius of a tampered artifact.

Content

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

bash
sudo mkdir -p /opt/<app>
sudo cp -r <解压目录>/bin /opt/<app>/
sudo ln -sf /opt/<app>/bin/ffmpeg /usr/local/bin/ffmpeg-gpu   # 建符号链接到 PATH
  • 系统级安装用 /opt/ + /usr/local/bin/ 链接;用户级安装放 ~/.local/bin/
  • 装完删除下载的压缩包(节省磁盘),保留解压目录(方便排查)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The eval prompts drive broad operational behavior such as cloning repositories recursively, downloading release assets via proxies/mirrors, extracting artifacts, and installing or locating executables, but they do not define trust boundaries, allowed sources beyond GitHub, or exclusions for dangerous content. In a network/file-system capable skill, this can normalize fetching and unpacking untrusted third-party content and encourage over-broad invocation behavior, increasing the chance of supply-chain abuse, unsafe extraction, or use in contexts where stricter validation should apply.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring, usage text, and user-facing descriptions are written entirely in Chinese, which imposes a specific language on users without any opt-in or alternative locale support. The stated policy requires flagging language or locale constraints unless the skill explicitly offers a choice or clearly documents a justified regional limitation.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/github_fetch.py (reported line 53)May include surrounding context.

python
return 0.0


def _run(cmd, timeout=None, **kw):
    return subprocess.run(cmd, capture_output=True, text=True, timeout=timeout, **kw)

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/github_fetch.py (reported line 54)May include surrounding context.

python
def _run(cmd, timeout=None, **kw):
    return subprocess.run(cmd, capture_output=True, text=True, timeout=timeout, **kw)


def probe_speed(url: str, timeout: int = 15) -> tuple[bool, float, int]:

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/github_fetch.py (reported line 60)May include surrounding context.

python
def probe_speed(url: str, timeout: int = 15) -> tuple[bool, float, int]:
    """测速:请求前 1MB。返回 (可用, 速度B/s, http状态码)。206=支持range(可续传)。"""
    try:
        r = subprocess.run(
            ["curl", "-sL", "-o", "/dev/null", "-r", "0-1048575",
             "-w", "%{http_code} %{speed_download}", url],
            capture_output=True, text=True, timeout=timeout)

Tainted flow: 'url' from os.environ.get (line 265, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
82% confidence
Finding

The tool accepts proxy prefixes from the GITHUB_PROXIES environment variable and later combines them with target GitHub URLs, causing network requests to attacker-controlled endpoints if that environment variable is influenced externally. In this skill's context, that is meaningful because the tool is explicitly designed to fetch binaries and archives, so a hostile proxy can observe requests, supply malicious content, or redirect integrity checks unless strict verification is enforced.

Content

Scanner excerpt · scripts/github_fetch.py (reported line 60)May include surrounding context.

python
def probe_speed(url: str, timeout: int = 15) -> tuple[bool, float, int]:
    """测速:请求前 1MB。返回 (可用, 速度B/s, http状态码)。206=支持range(可续传)。"""
    try:
        r = subprocess.run(
            ["curl", "-sL", "-o", "/dev/null", "-r", "0-1048575",
             "-w", "%{http_code} %{speed_download}", url],
            capture_output=True, text=True, timeout=timeout)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The install routine copies downloaded content into an installation directory and can create symlinks under /usr/local/bin, which changes persistent system state and may make untrusted binaries easily executable system-wide. In this skill's context, that is more dangerous because the script fetches from third-party mirrors and can extract arbitrary archives before installation.

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 · SKILL.md (reported line 43)May include surrounding context.

md
def resolve_release(owner_repo: str, tag: str = "latest",
                    pattern: str = None, proxies: list[str] = None) -> str:
    """查 release 资产 URL。tag 缺省 latest;pattern 正则匹配资产名(默认第一个)。"""
    api = f"https://api.github.com/repos/{owner_repo}/releases/{tag}"
    r = _run(["curl", "-sL", api], timeout=30)
    try:
        data = json.loads(r.stdout)

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/github_fetch.py (reported line 179)May include surrounding context.

python
def resolve_release(owner_repo: str, tag: str = "latest",
                    pattern: str = None, proxies: list[str] = None) -> str:
    """查 release 资产 URL。tag 缺省 latest;pattern 正则匹配资产名(默认第一个)。"""
    api = f"https://api.github.com/repos/{owner_repo}/releases/{tag}"
    r = _run(["curl", "-sL", api], timeout=30)
    try:
        data = json.loads(r.stdout)

External Script Fetching

Low
Category
Supply Chain
Confidence
15% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

查最新 release 资产列表(脚本 --release 参数已封装):

bash
curl -s "https://api.github.com/repos/{owner}/{repo}/releases/latest" | python3 -m json.tool

注意:BtbN 等仓库的 releases/latest 的 tag_name 是字面量 latest,资产 URL 用 releases/download/latest/{asset}。

Static analysis

No suspicious patterns detected.