Back to skill

Security audit

Tencent Ima Skill Publish

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with IMA note and knowledge-base management, but it has unsafe credential handling and remote update-instruction behavior that users should review before installing.

Install only if you trust the publisher and are comfortable granting IMA note and knowledge-base read/write access. Avoid setting IMA_BASE_URL or HERMES_ENV, treat update instructions returned by the service as untrusted display text, do not let the agent print or cat credential files, and prefer a safer secret store or tightly permissioned env injection for the IMA API key.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (5)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:419
Finding

Remote API Response Can Inject Instructions into Agent Behavior

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
ima_api.cjs:65
Finding

IMA Credentials Can Be Redirected to an Arbitrary Base URL

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
bin/ima.sh:17
Finding

Credential Configuration File Is Executed as Arbitrary Shell Code

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/build_kb_structure.py:34
Finding

Unsanitized Knowledge-Base Identifiers Are Evaluated as JavaScript Source

Content
View full analysis
{\n" " const d=JSON.parse(r);\n" " process.stdout.write(JSON.stringify({code:d.code, mid:d.data && d.data.media_id, msg:d.msg}));\n" "}).catch(e=>{console.error(e.message); process.exit(1);});\n" ) r = subprocess.run(["node", "-e", node_code], capture_output=True, text=True) ``` ### Technical Analysis The utility generates executable JavaScript source and supplies it to `node -e`. The command-line `kb_id` value and the `parent_id` value are concatenated between single quotes without escaping or syntax validation. Although `subprocess.run` uses an argument array and does not invoke a shell, that does not prevent this vulnerability. The injection occurs in JavaScript source interpreted by Node, not in shell parsing. A value containing a quote can terminate the intended string and insert arbitrary JavaScript statements. The folder name is serialized with `json.dumps`, but the identifiers are not. The hardcoded JavaScript file path is not attacker-controlled through normal script arguments, but the untrusted identifier alone is sufficient for source injection. ### Attack Path 1. An attacker suppli ...[truncated 1153 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
bin/ima.sh:401
Finding

Temporary COS Credentials Are Exposed in Process Command-Line Arguments

Content
View full analysis
Remediation
View remediation
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (72)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

There is a material description-behavior mismatch. The description presents a broad end-user skill for knowledge-base and note operations: uploading files, adding web content, searching the knowledge base, and browsing/creating/editing notes. The actual code chunk only builds a hardcoded hierarchical folder structure in an existing knowledge base using the create_folder API. While folder creation is related to knowledge-base management, it is a narrower and different capability than the declared main functions, and it introduces an undeclared specific behavior (batch directory tree creation). Therefore the supplied code does not accurately represent the declared skill behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The trigger conditions are extremely broad, including everyday phrases like '帮我记一下', '记录一下', and general personal document access intent. This can cause the skill to activate in contexts where the user did not intend to invoke external networked storage, increasing the risk of accidental data disclosure or unintended writes to a third-party service.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The skill instructs the agent to enumerate credentials from environment variables and ~/.hermes/.env, which normalizes direct secret discovery and handling from local storage. Even if intended only for validation, this expands secret exposure in the agent context and increases the chance of accidental leakage through logs, command output, error reporting, or prompt inclusion.

Content

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

md
> ⚠️ **v14 实战新增关键约束**(2026-06-05 凭证检测失误被用户当场纠正时实测):
> 1. **凭证检测必须先看环境变量再看文件** —— SKILL.md 写明优先级"环境变量 → 配置文件",但 agent 容易写成只检测文件路径的脚本(`test -f ~/.config/ima/client_id && test -f ~/.config/ima/api_key`),漏检 `IMA_OPENAPI_CLIENTID` / `IMA_OPENAPI_APIKEY` 这两个环境变量,得到**假阴性**"⚠️ 凭证缺"。**正确姿势**(按优先级):
>    1. `env | grep -E '^(IMA_OPENAPI_CLIENTID|IMA_OPENAPI_APIKEY)='` 看 shell 环境
>    2. `grep -E 'IMA_OPENAPI_(CLIENTID|APIKEY)' ~/.hermes/.env` 看 .env 文件
>    3. `ls ~/.config/ima/{client_id,api_key}` 看配置文件(最低优先级)
>    **任一在 = 凭证在**。**不要**只看文件路径就下结论。**真实失误案例**:2026-06-05 用户要求"继续进行 ima 的知识获取与筛选" → agent 只跑文件检测就报"⚠️ 凭证缺,先补才能写操作" → 用户当场纠正"ima凭证是什么?我理解我配置 ima 技能的时候已经加入了。不是吗" → 实际凭证在 `~/.hermes/.env` + shell export 完整在位。
> 2. **不要把"凭证检测失败"扩大成"写操作前必须先补凭证"** —— 这是同一失误的连锁反应。看到 ⚠️ 之前先按上面的 1+2+3 优先级**完整**查一遍再下结论。

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 · SKILL.md (reported line 83)May include surrounding context.

md
> 1. **`mmx text chat` 没有 `--output text` 标志**(`mmx text chat --help` 显示的 `--output json` 是 global flag,不是 sub flag)—— stdout **直接**返回 JSON object `{"id","type","role","model","content":[{"type":"thinking"},{"type":"text"}],"usage","stop_reason","base_resp"}`,**不会**带 `--output` 选项。提取文本:遍历 `j["content"]` 找 `c["type"]=="text"` 的 `c["text"]`。**`--output text` 是假选项**(会静默返回 1 字符 stdout,不要浪费时间解析)。
> 2. **"直接当译文" 模式(v14 新增简化路径)** —— 当源仓库**已经是中文**(如 `AlexAnys/awesome-openclaw-usecases-zh`、`xianyu110/awesome-openclaw-tutorial` 等),不需要走 `mmx text chat` 翻译 + 8 校验的完整流水线。简化流程:① 读 H1 ② GATE 3 预检(`check-name` 必跑)③ 复制到沙箱按 H1 命名 ④ `upload-file` 走 4 步门。**省 50%+ 时间**(从 110s/批 → ~20s/批),质量**不**降(源已经是中文,机翻是退化)。
> 3. **8 篇 0 GATE 3 实测**(2026-06-05 验证):8 篇纯增量中文用例(`A 股每日行情监控.md` / `用 Lark CLI 让 Agent 操作飞书.md` 等),GATE 3 全部 `is_repeated: false`,**没有任何冲突**。`browse-kb` 验证后子文件夹从 42 → 50。**结论**:纯增量内容(slug 命名不同时)GATE 3 命中率极低,`--force` 几乎用不到。
> 4. **subprocess shell=True 中文文件名解析坑**(2026-06-05 实战)—— 用 `subprocess.run(["~/.hermes/skills/ima/bin/ima", "check-name", KB_ID, "A 股每日行情监控.md", ...], shell=True)` 调中文文件名时,**shell 解析会把空格当分隔符**,导致传进去的字段被拆,**JSON 返回成功但解析失败**(`ParseExpecting value: line 1 column 1 (char 0)`)。**正确做法**:直接 `subprocess.run([...], shell=False)` 用 argv 形式传参,或用 `terminal()` 工具调 `~/.hermes/skills/ima/bin/ima check-name ...`。Python 解析 JSON 时**不要** `shell=True` + 中文字符串。
> 5. **frontmatter `source:` 字段按仓库区分**(v14 新增约定)—— 50 篇 vault 笔记的 frontmatter,42 篇用 `source: hesamsheikh/awesome-openclaw-usecases`、8 篇用 `source: AlexAnys/awesome-openclaw-usecases-zh`。**不要统一**写成"OpenClaw 用例",否则未来想做"按仓库分类"双链聚合时区分不出来。
>
> 详见 `references/api-quirks.md` v14 段(待补)。

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The credential-check workflow explicitly probes whether secrets are present in environment variables or files under the user's home directory. This pattern encourages the agent to inspect sensitive locations and can inadvertently expose authentication material during troubleshooting or transcript capture.

Content

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

bash
# 完整凭证检测(先 env var,后文件)
if [ -n "$IMA_OPENAPI_CLIENTID" ] && [ -n "$IMA_OPENAPI_APIKEY" ]; then
  echo "✅ 凭证在环境变量(.env 已加载)"
elif [ -f ~/.config/ima/client_id ] && [ -f ~/.config/ima/api_key ]; then
  echo "✅ 凭证在 ~/.config/ima/ 文件"
else

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The document directs operators to run env | grep IMA and inspect ~/.hermes/.env, which is explicit credential harvesting guidance. In an adversarial or misconfigured environment, this can leak secrets into terminal logs, model context, or debugging artifacts and weakens the boundary between secret existence checks and secret retrieval.

Content

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

md
**含义**:
- "看起来缺 vs 实际在"是高频陷阱——**永远跑实测命令**验证配置状态
- 用户环境跟 SKILL.md 默认假设("凭证在文件里")不一致是常态
- 看到"凭证缺"信号 → **先**用 `env | grep IMA` + `cat ~/.hermes/.env | grep -i ima` 跑实测,**再**下结论

### 发现 3:批量传 KB 后的"实际落点"核验模式

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The setup instructions tell users to place long-lived API credentials into ~/.config/ima/* or ~/.hermes/.env, both of which are accessible from local shell tooling used by the skill. Persisting reusable API keys in plaintext expands the blast radius of any shell misuse, prompt injection, or local compromise.

Content

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

echo "your_api_key" > ~/.config/ima/api_key

text

**方式 B — 环境变量(推荐,~./hermes/.env 已留行):**

```bash
# 编辑 ~/.hermes/.env,找到这两行(开头的 # 已注释),替换占位值

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

md
body: { file_name, file_size, content_type, knowledge_base_id, file_ext }
         响应: { data: { media_id, cos_credential: { cos_key, bucket_name, region, secret_id, secret_key, token, start_time, expired_time } } }
         ⚠️ cos_* 字段全部嵌套在 cos_credential,**顶层只有 media_id**
GATE 5: cos-upload  → 走腾讯云 COS SDK PUT 文件,用 create_media 返回的临时 token(不是 .env 里的 API key)
GATE 2: add_knowledge (openapi/wiki/v1/add_knowledge)
         body: { media_type, media_id, title, knowledge_base_id, file_info: { cos_key, file_size, file_name } }
         title 必须 == file_name

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

md
body: { file_name, file_size, content_type, knowledge_base_id, file_ext }
         响应: { data: { media_id, cos_credential: { cos_key, bucket_name, region, secret_id, secret_key, token, start_time, expired_time } } }
         ⚠️ cos_* 字段全部嵌套在 cos_credential,**顶层只有 media_id**
GATE 5: cos-upload  → 走腾讯云 COS SDK PUT 文件,用 create_media 返回的临时 token(不是 .env 里的 API key)
GATE 2: add_knowledge (openapi/wiki/v1/add_knowledge)
         body: { media_type, media_id, title, knowledge_base_id, file_info: { cos_key, file_size, file_name } }
         title 必须 == file_name

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

md
body: { file_name, file_size, content_type, knowledge_base_id, file_ext }
         响应: { data: { media_id, cos_credential: { cos_key, bucket_name, region, secret_id, secret_key, token, start_time, expired_time } } }
         ⚠️ cos_* 字段全部嵌套在 cos_credential,**顶层只有 media_id**
GATE 5: cos-upload  → 走腾讯云 COS SDK PUT 文件,用 create_media 返回的临时 token(不是 .env 里的 API key)
GATE 2: add_knowledge (openapi/wiki/v1/add_knowledge)
         body: { media_type, media_id, title, knowledge_base_id, file_info: { cos_key, file_size, file_name } }
         title 必须 == file_name

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

md
body: { file_name, file_size, content_type, knowledge_base_id, file_ext }
         响应: { data: { media_id, cos_credential: { cos_key, bucket_name, region, secret_id, secret_key, token, start_time, expired_time } } }
         ⚠️ cos_* 字段全部嵌套在 cos_credential,**顶层只有 media_id**
GATE 5: cos-upload  → 走腾讯云 COS SDK PUT 文件,用 create_media 返回的临时 token(不是 .env 里的 API key)
GATE 2: add_knowledge (openapi/wiki/v1/add_knowledge)
         body: { media_type, media_id, title, knowledge_base_id, file_info: { cos_key, file_size, file_name } }
         title 必须 == file_name

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 · bin/ima.sh (reported line 472)May include surrounding context.

sh
body: { file_name, file_size, content_type, knowledge_base_id, file_ext }
         响应: { data: { media_id, cos_credential: { cos_key, bucket_name, region, secret_id, secret_key, token, start_time, expired_time } } }
         ⚠️ cos_* 字段全部嵌套在 cos_credential,**顶层只有 media_id**
GATE 5: cos-upload  → 走腾讯云 COS SDK PUT 文件,用 create_media 返回的临时 token(不是 .env 里的 API key)
GATE 2: add_knowledge (openapi/wiki/v1/add_knowledge)
         body: { media_type, media_id, title, knowledge_base_id, file_info: { cos_key, file_size, file_name } }
         title 必须 == file_name

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 · references/ima-write-flow.md (reported line 31)May include surrounding context.

md
body: { file_name, file_size, content_type, knowledge_base_id, file_ext }
         响应: { data: { media_id, cos_credential: { cos_key, bucket_name, region, secret_id, secret_key, token, start_time, expired_time } } }
         ⚠️ cos_* 字段全部嵌套在 cos_credential,**顶层只有 media_id**
GATE 5: cos-upload  → 走腾讯云 COS SDK PUT 文件,用 create_media 返回的临时 token(不是 .env 里的 API key)
GATE 2: add_knowledge (openapi/wiki/v1/add_knowledge)
         body: { media_type, media_id, title, knowledge_base_id, file_info: { cos_key, file_size, file_name } }
         title 必须 == file_name

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring says the function recursively builds a directory tree, and the recursive call passes parent_id=mid to place subfolders under the created parent. However, build_kb is defined without a parent_id parameter, and create_folder is always called as create_folder(kb_id, name) with no parent, so the documented nested-tree behavior is not what the code actually performs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The verification step instructs users to export API credentials directly in the shell command line, which can expose secrets through shell history, process inspection, terminal logs, or copy/paste artifacts. In a publishing guide for a skill that handles user knowledge bases and notes, normalizing plaintext credential handling increases the chance of credential leakage during setup and testing.

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

bash
# 1) 下载官方 OpenAPI 包
curl -sS -o /tmp/ima.zip https://app-dl.ima.qq.com/skills/ima-skills-1.1.7.zip

# 2) 解压到 hermes skills 目录
mkdir -p ~/.hermes/skills/ima

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 33)May include surrounding context.

md
curl -sS -o /tmp/ima.zip https://app-dl.ima.qq.com/skills/ima-skills-1.1.7.zip

# 2) 解压到 hermes skills 目录
mkdir -p ~/.hermes/skills/ima
unzip -q /tmp/ima.zip -d /tmp/ima-extract
cp -r /tmp/ima-extract/ima-skill/* ~/.hermes/skills/ima/

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 33)May include surrounding context.

md
curl -sS -o /tmp/ima.zip https://app-dl.ima.qq.com/skills/ima-skills-1.1.7.zip

# 2) 解压到 hermes skills 目录
mkdir -p ~/.hermes/skills/ima
unzip -q /tmp/ima.zip -d /tmp/ima-extract
cp -r /tmp/ima-extract/ima-skill/* ~/.hermes/skills/ima/

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

md
# 4) 配凭证
echo 'IMA_OPENAPI_CLIENTID=your-client-id' >> ~/.hermes/.env
echo 'IMA_OPENAPI_APIKEY=your-api-key' >> ~/.hermes/.env
chmod 600 ~/.hermes/.env

# 5) 验证
~/.hermes/skills/ima/bin/ima.sh list-kb

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The roadmap states delete/move/rename-related instructions are not in OpenAPI scope and should be done manually, yet the same manifest declares newly discovered endpoints including rename_note, create_folder, create_knowledge_base, move_knowledge, add_notebook, and rename_notebook. This creates a semantic mismatch about what modification capabilities the skill actually exposes versus what it says remains out of scope.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The document states that a mandatory UTF-8 rule is fully retained, and later frames UTF-8 validation/conversion as required before note writes. This imposes a specific encoding/locale handling requirement rather than offering user choice, which can be a language/locale policy constraint in natural-language instructions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The roadmap note says users must perform delete, move, and rename actions manually in the IMA client, but later sections document rename-note <note_id> <new_title> as a valid supported command for true note media and describe its constraints in detail. That is an active contradiction in the skill's own intent documentation, not merely an omission.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
1. **UTF-8 encoding (notes writes only):** Before calling `import_doc` or `append_doc`, ALL string fields (`content`, `title`) MUST be validated as legal UTF-8. Non-UTF-8 content causes irreversible garbled text. See [Detailed Rules](#detailed-utf-8-encoding-rules) for platform-specific methods.
2. **File upload naming:** `title` MUST equal `file_name` (with extension). Never rename, shorten, translate, or modify the original filename.
3. **Unsupported file types:** Reject immediately with a clear message. Do NOT ask user "do you still want to try?" Video files, Bilibili/YouTube URLs, and `file://` URLs are not supported — tell user to use IMA desktop client.
4. **File upload integrity:** Keep file content as-is during upload. No encoding conversion for binary files (PDF, images, Excel, etc.).
5. **PowerShell 5.1 (all modules):** If running in PowerShell, detect version before first API call. PS 5.1 silently converts request Body to GBK — must use UTF-8 byte array mode. See [Detailed Rules](#powershell-51-environment-detection).

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

This duplicated finding points to the same session-persistence behavior: storing reusable credentials in local files or .env. The risk is not immediate remote exploitation, but increased exposure duration and accessibility of secrets to local processes and transcripts.

Content

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

方式 A — 配置文件:

bash
mkdir -p ~/.config/ima
echo "your_client_id" > ~/.config/ima/client_id
echo "your_api_key" > ~/.config/ima/api_key

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
ima_api.cjs:31

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
knowledge-base/scripts/cos-upload.cjs:96