Back to skill

Security audit

git-sync

Security checks across malware telemetry and agentic risk

Overview

This is a legitimate publishing automation skill, but it needs Review because it can use and alter local credentials while pushing, publishing, and creating releases across external services.

Install only if you intentionally want this skill to have release/publishing authority for your local skill or agent repos. Run it in an isolated workspace/account, review config.json and remotes first, avoid plaintext or URL-embedded credentials, and prefer explicit flags such as skip-market or release only when you mean to publish. Do not use it on untrusted projects until the shell=True publisher call, global git credential changes, and cleanup boundary are fixed.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (43)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = f'npx clawhub publish "{sd}" --slug "{slug}" --name "{meta.get("displayName",name)}" --version "{version}" --changelog "v{version}"'
    if meta.get("tags"):
        cmd += ' --tags "' + ",".join(meta["tags"]) + '"'
    r = subprocess.run(cmd, capture_output=True, text=True, shell=True)
    if r.returncode==0 or "ok" in r.stdout.lower(): print(f"  ✅ ClawHub: {slug}")
    else: print(f"  ⚠️  ClawHub: {r.stderr[:200]}")
Confidence
99% confidence
Finding
r = subprocess.run(cmd, capture_output=True, text=True, shell=True)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
_env = os.environ.copy()
    _env["GIT_TERMINAL_PROMPT"] = "0"
    # 写入 repo 级配置(最高优先级,覆盖全局)
    _sp.run(
        ["git", "config", "credential.helper", "store"],
        cwd=str(WORK_REPO), capture_output=True, check=False, env=_env
    )
Confidence
97% confidence
Finding
_sp.run( ["git", "config", "credential.helper", "store"], cwd=str(WORK_REPO), capture_output=True, check=False, env=_env )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cwd=str(WORK_REPO), capture_output=True, check=False, env=_env
    )
    # 写入全局配置(防止 repo 级失败)
    _sp.run(
        ["git", "config", "--global", "credential.helper", "store"],
        capture_output=True, check=False, env=_env
    )
Confidence
98% confidence
Finding
_sp.run( ["git", "config", "--global", "credential.helper", "store"], capture_output=True, check=False, env=_env )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
b = json.dumps({"tag_name":tag,"name":f"{name} v{version}",
                        "body":f"## {name} v{version}\n\n由 git-sync 自动发布",
                        "draft":False,"prerelease":False})
        r = subprocess.run(["curl","-s","-X","POST",
                         f"https://api.github.com/repos/{GITHUB}/releases",
                         "-H",f"Authorization: token {token}","-H","Content-Type: application/json","-d",b],
                        capture_output=True,text=True)
Confidence
95% confidence
Finding
r = subprocess.run(["curl","-s","-X","POST", f"https://api.github.com/repos/{GITHUB}/releases", "-H",f"Authorization: token {token}","-H","Con

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"target_commitish":"main","name":f"{name} v{version}",
                        "body":f"## {name} v{version}\n\n由 git-sync 自动发布",
                        "prerelease":False})
        r = subprocess.run(["curl","-s","-X","POST",
                         f"https://gitee.com/api/v5/repos/{GITEE}/releases",
                         "-H","Content-Type: application/json;charset=UTF-8","-d",b],
                        capture_output=True,text=True)
Confidence
92% confidence
Finding
r = subprocess.run(["curl","-s","-X","POST", f"https://gitee.com/api/v5/repos/{GITEE}/releases", "-H","Content-Type: application/json;charset=

subprocess module call

Medium
Category
Dangerous Code Execution
Content
for rm in ["gitee","origin"]:
        subprocess.run(["git","push",rm,tag],cwd=str(_rel_repo),capture_output=True,timeout=30)
        subprocess.run(["git","push",rm,pypi_tag],cwd=str(_rel_repo),capture_output=True,timeout=30)
    rmt = subprocess.run(["git","remote","get-url","origin"],cwd=str(_rel_repo),
                         capture_output=True,text=True).stdout.strip()
    token = ""
    if ":" in rmt and "@" in rmt:
Confidence
96% confidence
Finding
rmt = subprocess.run(["git","remote","get-url","origin"],cwd=str(_rel_repo), capture_output=True,text=True).stdout.strip()

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# build (only wheel, no sdist)
    print(f"  构建 {pypi_name} v{version}...")
    result = subprocess.run(
        [sys.executable, "-m", "build", "--wheel"],
        cwd=build_dir, capture_output=True, text=True
    )
Confidence
94% confidence
Finding
result = subprocess.run( [sys.executable, "-m", "build", "--wheel"], cwd=build_dir, capture_output=True, text=True )

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

Medium
Category
Data Flow
Content
shutil.rmtree(build_dir,ignore_errors=True); return
    whl = build_dir / "dist" / f"{pypi_name.replace('-','_')}-{pypi_ver}-py3-none-any.whl"
    if whl.exists():
        r = subprocess.run([sys.executable,"-m","twine","upload","--disable-progress",str(whl),"-u","__token__","-p",token],
                          capture_output=True,text=True,cwd=str(build_dir))
        if r.returncode==0: log(8,8,f"PyPI: https://pypi.org/project/{pypi_name}/","ok")
        else: log(8,8,f"PyPI 上传失败: {r.stderr[:200]}","err")
Confidence
90% confidence
Finding
r = subprocess.run([sys.executable,"-m","twine","upload","--disable-progress",str(whl),"-u","__token__","-p",token], capture_output=True,text=True,cwd=str(build_dir))

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill advertises broad capabilities including environment access, file read/write, network transmission, and shell execution, but does not declare a granular permissions model in the metadata. For a publishing tool that can push code to external platforms and manipulate repository contents, this creates a real trust and consent gap: callers may invoke a highly privileged workflow without clear permission boundaries or user confirmation expectations.

Tp4

High
Category
MCP Tool Poisoning
Confidence
86% confidence
Finding
The documented purpose emphasizes synchronization and publishing, but the behavior also includes repository rewriting, README regeneration, manifest database maintenance, local artifact cleanup, and auxiliary auditing logic. That mismatch is security-relevant because users may approve a publish operation without realizing the skill can modify additional local state and repository metadata beyond the intended target files.

Context-Inappropriate Capability

Low
Confidence
82% confidence
Finding
The guide explicitly instructs the AI/caller to automatically open a local HTML index via preview_url after each run, even though that action is ancillary to syncing and release creation. Automatically opening local generated content expands the skill's side effects and could expose local file metadata or trigger unnecessary rendering of attacker-influenced HTML.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The script's documented safety boundary says deletion should only occur in temporary directories containing '.tmp_zip', but the actual check allows any path containing 'temp' or 'tmp'. That mismatch can cause destructive deletion in unintended directories such as normal project folders or user paths with those substrings, which is especially risky in a release/sync tool that processes filesystem content automatically.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The tool's stated role is sync/release, but this block changes global and repo git credential behavior and creates `.git-credentials` on disk. That expands privilege and secret-handling scope in a way users may not expect, increasing the blast radius if the tool is abused or misconfigured.

Vague Triggers

Medium
Confidence
81% confidence
Finding
The trigger list includes broad phrases like sync/push/publish/upload/package/update README, which overlap with common benign requests and can cause this privileged skill to activate too easily. In context, accidental invocation is dangerous because the skill can write files, rewrite documentation, and transmit content to external services.

Vague Triggers

Medium
Confidence
79% confidence
Finding
The natural-language trigger criteria do not clearly require explicit publishing context, project selection, or destination confirmation. Because this is a high-permission skill with external transmission and file mutation, ambiguity in activation conditions materially increases the risk of unintended execution or overbroad interpretation of user requests.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill performs pushes and marketplace uploads using stored credentials and external network destinations, yet the description lacks a clear warning that local content may be transmitted off-system and authenticated tokens may be used. That omission weakens informed consent and increases the chance that sensitive code or metadata is published unexpectedly.

Vague Triggers

High
Confidence
94% confidence
Finding
The trigger phrase is extremely broad and bundles many common actions such as sync, push, publish, upload, package, update, and README updates into a single activation rule. In a release/deployment skill that can interact with multiple repositories and publishing targets, this raises the chance of accidental invocation and unintended code or artifact publication, which can lead to unauthorized releases or data exposure.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The workflow says the tool prints the complete file list and exclusion rules to stdout for AI review. In this skill's context, stdout may be captured by logs or shown to an LLM/caller, which can leak sensitive filenames, internal paths, and project structure beyond what is necessary for syncing.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The guide describes LLM-driven sensitive data handling with automatic keep/sanitize decisions but does not require human verification or warn about false negatives/positives. This can result in secrets being missed and published, or legitimate content being altered incorrectly, especially in a release automation pipeline.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The document explicitly classifies external network access as 'silent' execution, meaning data transmission to remote services can occur without an interactive warning. In a git synchronization/publishing skill that connects to third-party platforms, this increases the risk of unnoticed exfiltration of repository contents, metadata, or credentials and normalizes unsafe consent practices.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The document states that sensitive information access is covered by unified one-time authorization without a prominent warning about credential or privacy exposure. Because this skill handles git credentials and tokens across multiple platforms, broad persistent approval can allow repeated access to secrets after initial consent, reducing user visibility into high-risk operations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script reads files across the target skill directory, heuristically extracts lines likely to contain secrets, URLs, emails, paths, and key-value assignments, and then serializes those samples directly into JSON output. In the context of a cross-platform publishing/sync tool with LLM-driven filtering, this increases the chance that credentials or private data are exfiltrated into logs, artifacts, or downstream model inputs before any redaction decision is safely enforced.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script reads publishing credentials from `.pypirc` or the environment and uses them to upload to PyPI without an explicit user-facing confirmation step. In an agent/automation context, silent use of local secrets for external publication is especially risky because a crafted task or project can trigger unintended authenticated actions.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Release creation automatically uses credentials extracted from remotes or config and sends them in authenticated network requests. This is dangerous because it turns local credential material into outbound authority without transparent disclosure, enabling unintended release publication or abuse of privileged tokens.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script forcefully overwrites an existing tag locally (`git tag -f`) and force-pushes that tag to both remotes (`git push ... -f`) without any confirmation, safety check, or dry-run mode. This can silently rewrite release history, replace prior release artifacts, and cause downstream consumers or automation to trust the wrong code version.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.