Back to skill

Security audit

skill-publish-sync

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent publishing helper, but it should go to Review because it runs mutable remote tooling and can perform credentialed batch uploads with weak confirmation and input handling.

Install only if you are comfortable reviewing the scripts and running publishing tools with your local account. Avoid `curl | bash` and unpinned `npx` where possible, pin and verify CLI versions, run uploads from a constrained working copy, inspect the prepared `/tmp/*-publish-*` directory before pushing, and do not use the Lenovo batch uploader on untrusted skill metadata until version validation and manual confirmation are added.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:46
Finding

Mutable Remote Installer Is Piped Directly into Bash

Content
View full analysis
Remediation
View remediation
skillhub-install.sh' | sha256sum -c - ``` 6. Prefer a publisher signature using Sigstore, GPG, or an equivalent verifiable signing mechanism. 7. Execute the downloaded file only after successful verification: ```bash bash skillhub-install.sh ``` 8. Document the expected files, permissions, network endpoints, and configuration changes made by the installer. 9. Avoid requesting elevated privileges unless a specific installation step demonstrably requires them. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/push-lenovo-batch.sh:25
Finding

Unpinned npm CLI Is Automatically Downloaded and Executed

Content
View full analysis
/dev/null 2>&1; then ``` ```tcl spawn $NPM_CMD push --zipAbsPath $ZIP_FILE ``` The documentation also recommends dynamically resolving the latest package: ```bash # Method 1: npx (recommended, no installation, always latest) npx @lenovo-open/skill-cli # Method 2: global installation npm install -g @lenovo-open/skill-cli ``` ### Technical Analysis The batch uploader uses `npx -y` without an exact package version, lockfile, or repository-controlled integrity value. This causes npm to resolve and execute whichever release is current at runtime while suppressing the normal installation confirmation. The executed package is therefore not necessarily the package version reviewed when this Skill was audited. npm package code and its dependency graph can execute with the current user’s permissions, including through CLI startup code and potentially lifecycle scripts. Use of the Lenovo CLI is relevant to the declared publishing function. However, automatically trusting the latest registry release is broader than necessary and creates an avoidable supply-chain execution channel. ### Attack Path 1. An attacker compromises the npm publisher account, the package release pipeline, or a transitive dependency. 2. The attacker publishes a malicious version that satisfies the unpinned package reference. 3. An operator runs `push-lenovo-batch.sh`. 4. `npx -y` resolves and downloads the malicious release without requesting confirmation. 5. npm or the CLI executes attacker-controlled ...[truncated 965 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/push-lenovo-batch.sh:85
Finding

Skill Version Metadata Can Inject Tcl Commands into the Expect Program

Content
View full analysis
Remediation
View remediation
&2 exit 1 fi ``` 2. Do not interpolate shell variables directly into generated Tcl source. 3. Pass dynamic values through the environment and read them as data from Tcl: ```bash export PUBLISH_VERSION="$VER" export ZIP_FILE ``` ```tcl set version $env(PUBLISH_VERSION) set zip_file $env(ZIP_FILE) send -- "v${version}: Batch synchronization to Lenovo Open Platform\r" ``` 4. Pass command arguments through structured Tcl lists instead of constructing a command line: ```tcl spawn {*}[list npx -y @lenovo-open/skill-cli@1.2.3 push --zipAbsPath $zip_file] ``` 5. Apply strict validation to `SKILL`, `ZIP_FILE`, display names, and all metadata crossing from YAML or Markdown into shell, JSON, Tcl, or command arguments. 6. Generate `.skill-config.json` using a JSON library rather than a heredoc, ensuring quotes, backslashes, control characters, and newlines are escaped correctly. 7. Add regression tests using metadata containing Tcl metacharacters, quotes, backslashes, newlines, command substitutions, and malformed SemVer values. ]]>
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (28)

External Script Fetching

High
Category
Supply Chain
Confidence
98% confidence
Finding

curl -fsSL ... | bash downloads and immediately executes a remote script without verification, giving the script full code execution on the host. If the hosting endpoint, transport, or upstream content is compromised, an attacker can run arbitrary commands, install persistence, or steal publishing credentials.

Content

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

bash
# 1. 安装 CLI(macOS/Linux)
curl -fsSL https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/install/install.sh | bash

# 2. 升级到支持发布的版本(≥ 2026.7.29)
skillhub self-upgrade

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The command chaining pattern | bash turns a network fetch into immediate shell execution, removing any review boundary between download and execution. In the context of a publishing skill that may run where tokens and repository contents are present, this materially increases the risk of host compromise and credential theft.

Content

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

bash
# 1. 安装 CLI(macOS/Linux)
curl -fsSL https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/install/install.sh | bash

# 2. 升级到支持发布的版本(≥ 2026.7.29)
skillhub self-upgrade

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> - "Do not add conflicting license terms in `SKILL.md`." —— **禁止在 SKILL.md 内加冲突的许可证条款**。

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/prepare-publish.sh (reported line 148)May include surrounding context.

sh
--exclude='node_modules/'  # 排除 node_modules
    --exclude='__pycache__/'   # 排除 Python 缓存
    --exclude='.DS_Store'      # 排除 macOS 系统文件
    --exclude='**/.env'        # 排除环境变量文件(防止凭证泄露)
    --exclude='**/*.db'        # 排除数据库文件
    --exclude='**/*.sqlite'    # 排除 SQLite 文件
    --exclude='**/logs/'       # 排除日志目录

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/prepare-publish.sh (reported line 209)May include surrounding context.

sh
# 强制清理 rsync 可能遗漏的运行时目录(.gitignore 路径相对于项目根时 rsync 无法匹配)
for _DIR in archive output downloads logs; do
    [ -d "$TEMP_DIR/$_DIR" ] && rm -rf "$TEMP_DIR/$_DIR" && echo -e "${YELLOW}强制移除: $_DIR/${NC}"
done

# 清理 .gitkeep 占位文件(git 用来追踪空目录,非 skill 内容;部分平台如 SkillHub 拒收该文件类型)

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/prepare-publish.sh (reported line 209)May include surrounding context.

sh
# 强制清理 rsync 可能遗漏的运行时目录(.gitignore 路径相对于项目根时 rsync 无法匹配)
for _DIR in archive output downloads logs; do
    [ -d "$TEMP_DIR/$_DIR" ] && rm -rf "$TEMP_DIR/$_DIR" && echo -e "${YELLOW}强制移除: $_DIR/${NC}"
done

# 清理 .gitkeep 占位文件(git 用来追踪空目录,非 skill 内容;部分平台如 SkillHub 拒收该文件类型)

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill describes capabilities that read environment-derived credentials and update local files such as sync records, but it does not declare any explicit tool scope or permission boundaries. In an agent setting, this increases the chance that the skill is invoked with broader-than-necessary file write or secret access, especially because it handles publishing tokens and local config state.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger description is broad enough that an agent may invoke the skill for general publishing, syncing, or status-check tasks without strong exclusion criteria. In a skill that performs packaging, uploads, auth checks, temp-directory creation, and local file updates, over-broad triggering raises the risk of unintended publication or modification actions.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
| 依赖 | 用途 | 安装方式 |
|------|------|----------|
| `rsync` | `prepare-publish.sh` 复制过滤文件到临时发布目录 | macOS 自带;Linux: `sudo apt-get install rsync` |
| `git` | `prepare-publish.sh` 用 `git ls-files` 精确匹配追踪文件 | macOS 自带;Linux: `sudo apt-get install git` |
| Python 3 | 运行腾讯 SkillHub CLI(Python 脚本) | macOS 自带;Linux: `sudo apt-get install python3` |
| Node.js(≥ 18)+ `npm` | 运行联想 `lenovoskill` CLI(`npx @lenovo-open/skill-cli` 走 Node.js 运行时) | macOS 自带或 `brew install node`;Linux: `sudo apt-get install -y nodejs npm` |

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
| 依赖 | 用途 | 安装方式 |
|------|------|----------|
| `rsync` | `prepare-publish.sh` 复制过滤文件到临时发布目录 | macOS 自带;Linux: `sudo apt-get install rsync` |
| `git` | `prepare-publish.sh` 用 `git ls-files` 精确匹配追踪文件 | macOS 自带;Linux: `sudo apt-get install git` |
| Python 3 | 运行腾讯 SkillHub CLI(Python 脚本) | macOS 自带;Linux: `sudo apt-get install python3` |
| Node.js(≥ 18)+ `npm` | 运行联想 `lenovoskill` CLI(`npx @lenovo-open/skill-cli` 走 Node.js 运行时) | macOS 自带或 `brew install node`;Linux: `sudo apt-get install -y nodejs npm` |

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
| 依赖 | 用途 | 安装方式 |
|------|------|----------|
| `rsync` | `prepare-publish.sh` 复制过滤文件到临时发布目录 | macOS 自带;Linux: `sudo apt-get install rsync` |
| `git` | `prepare-publish.sh` 用 `git ls-files` 精确匹配追踪文件 | macOS 自带;Linux: `sudo apt-get install git` |
| Python 3 | 运行腾讯 SkillHub CLI(Python 脚本) | macOS 自带;Linux: `sudo apt-get install python3` |
| Node.js(≥ 18)+ `npm` | 运行联想 `lenovoskill` CLI(`npx @lenovo-open/skill-cli` 走 Node.js 运行时) | macOS 自带或 `brew install node`;Linux: `sudo apt-get install -y nodejs npm` |

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
| 依赖 | 用途 | 安装方式 |
|------|------|----------|
| `rsync` | `prepare-publish.sh` 复制过滤文件到临时发布目录 | macOS 自带;Linux: `sudo apt-get install rsync` |
| `git` | `prepare-publish.sh` 用 `git ls-files` 精确匹配追踪文件 | macOS 自带;Linux: `sudo apt-get install git` |
| Python 3 | 运行腾讯 SkillHub CLI(Python 脚本) | macOS 自带;Linux: `sudo apt-get install python3` |
| Node.js(≥ 18)+ `npm` | 运行联想 `lenovoskill` CLI(`npx @lenovo-open/skill-cli` 走 Node.js 运行时) | macOS 自带或 `brew install node`;Linux: `sudo apt-get install -y nodejs npm` |

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

Using npx @lenovo-open/skill-cli without a pinned version allows whatever package version is current at execution time to be fetched and run. If the upstream package is compromised or a breaking/malicious update is published, the skill could execute attacker-controlled code during login, packaging, or push operations.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

This is a duplicate occurrence of the same unpinned npx @lenovo-open/skill-cli pattern at the same line and carries the same supply-chain risk. Repetition in documentation can normalize unsafe installation and execution practices for users.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

The skill again instructs users to rely on an unpinned remote npm package at publish time. This is especially risky in a publishing workflow because the process may expose auth tokens, package contents, and filesystem context to any malicious code executed from the fetched package.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

Referencing an unpinned Lenovo CLI in the platform comparison section reinforces unsafe execution of mutable upstream code. In this context, the skill manages artifact packaging and upload, so compromised tooling could tamper with published content or steal local credentials.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

The installation instructions recommend npx use without version pinning, which creates a persistent supply-chain risk for every invocation. Because the command is intended for authentication and package upload, a compromised package could capture tokens or alter uploads.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

This occurrence continues the same pattern of runtime-fetching an unpinned npm package for privileged actions. The surrounding context makes it more dangerous because it is tied to a workflow that packages local content and interacts with remote publishing services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The comments specify that display_name is required to be a Chinese name (中文名), which imposes a locale/language constraint in the configuration guidance. There is no indication of user choice, opt-in, or a documented region-specific exception in this file.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The script executes a remote npm package via npx -y @lenovo-open/skill-cli without pinning an exact version or integrity hash, so every run may fetch whatever version is current at execution time. If the package is compromised, unpublished/replaced, or a malicious version is published, this script would run attacker-controlled code with the user's local privileges during a publishing workflow that likely has platform credentials available.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The expect block automatically answers the platform confirmation prompt with y, causing uploads to proceed without an explicit interactive confirmation from the operator at execution time. In a batch publishing skill, this increases the chance of accidental publication of unintended content or publication under the wrong account/project, especially because the script suppresses most command output and is designed to continue across many skills.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

L569 明确写明 Lenovo CLI 的命令行为、frontmatter 读取方式和 OAuth 流程“来自用户提供的材料,未独立实测”。但前文 L290-L308、L500-L531 等段落把这些联想平台步骤和元数据注入机制写成确定的执行工作流,形成文档内部对实现状态的直接矛盾。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language comments and usage guidance in this template are entirely in Chinese, with no indication that language selection is optional or that the file is intentionally limited to a Chinese-only audience. Under the policy for natural-language content, forcing a specific language without user opt-in can be a locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

All natural-language comments and operational guidance in this template are written in Chinese, with no indication that users may choose another language or that the file is intentionally limited to a Chinese-speaking or Lenovo-region audience. Under the policy rule for language/locale constraints, this is a natural-language policy concern because it imposes a specific language without opt-in or justification.

Content

No source excerpt is available for this finding.