Back to skill

Security audit

腾讯乐享知识库 Lexiang Knowledge Base

Security checks for vulnerabilities and agentic risk

Overview

This looks like a real Lexiang knowledge-base skill, but it needs Review because it can upload local files and asks agents to read credential-bearing MCP configuration.

Install only if you intentionally want an agent to operate your Lexiang knowledge base, including creating, editing, deleting, reverting, and uploading content. Do not sync untrusted folders, avoid directories containing symlinks, review dry-run upload plans, and keep tokens out of chat output. Prefer providing company_from yourself or via whoami rather than allowing routine reads of mcp.json.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/upload-files.py:162
Finding

Folder Upload Scanners Follow Symbolic Links Outside the Selected Directory

Content
View full analysis

Vulnerability Details

File Location: scripts/upload-files.py:162-184, 219-220; scripts/sync-folder.ts:224-256; references/folder-sync.md:19-23, 66-73
Vulnerability Type: Symbolic-link path escape leading to unintended file disclosure
Risk Level: Medium

Relevant Code

scripts/upload-files.py:162-184:

python
for file_path in folder.rglob('*'):
    if file_path.is_dir():
        continue

    # Check ignore patterns
    relative_path = str(file_path.relative_to(folder))
    should_ignore = any(p in relative_path for p in ignore_patterns)
    if should_ignore:
        continue

    # Check extension
    if extensions and file_path.suffix.lower() not in extensions:
        continue

    task = UploadTask(
        local_path=str(file_path),
        file_name=file_path.name,
        parent_entry_id=parent_entry_id,
        mime_type=get_mime_type(str(file_path)),
        file_size=file_path.stat().st_size,
        content_hash=compute_file_hash(str(file_path))
    )
    tasks.append(task)

scripts/upload-files.py:219-220:

python
with open("{task.local_path}", "rb") as f:
    requests.put(upload_url, data=f.read(), headers={{"Content-Type": "{task.mime_type}"}})

scripts/sync-folder.ts:224-256:

typescript
const entries = fs.readdirSync(absolutePath, { withFileTypes: true });

for (const entry of entries) {
  const relativePath = path.join(currentPath, entry.name);

  if (shouldIgnore(relativePath, config.ignoredPatterns)) {
    continue;
  }

  const entryAbsolutePath = path.join(basePath, relativePath);
  const stats = fs.statSync(entryAbsolutePath);

  if (entry.isDirectory()) {
    files.push({
      relativePath,
      absolutePath: entryAbsolutePath,
      isDirectory: true,
      lastModified: stats.mtime
    });

    files.push(...scanLocalDirectory(basePath, config, relativePath));
  } else {
    const ext = 
...[truncated 3276 chars]
Remediation
View remediation

Remediation Suggestions

  1. Reject symbolic links during scanning:

    • In Python, call file_path.lstat() or file_path.is_symlink() before any stat, hash, or read operation.
    • In TypeScript, call fs.lstatSync(entryAbsolutePath).isSymbolicLink() and skip symbolic links by default.
  2. Resolve and enforce containment:

    • Resolve the selected root once with realpath.
    • Resolve every candidate file with realpath.
    • Require the resolved candidate to be a descendant of the resolved root using path-component-aware comparison.
    • Reject candidates that resolve to the root's parent, a sibling directory, or another filesystem location.
  3. Revalidate immediately before upload. A file can be replaced with a symlink after scanning, so containment and file-type checks should occur again when opening the file.

  4. Where supported, open files using no-follow semantics and verify the opened file descriptor rather than relying solely on pathname checks.

  5. Make the upload plan clearly report skipped symlinks and resolved-path violations so users can identify malicious or unexpected directory contents.

  6. Add regression tests covering:

    • File symlinks to targets outside the upload root.
    • Symlinks whose names use allowed extensions.
    • Directory symlinks.
    • Relative and absolute symlink targets.
    • Replacement of a validated file with a symlink between scanning and upload.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (55)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description claims a comprehensive 乐享知识库 skill covering many classes of operations across the knowledge base. The supplied code chunk, however, is specifically a file upload script: it builds upload tasks from local files/folders, computes hashes and MIME types, generates MCP calls for apply/commit upload, and can upload file content to pre-signed URLs. This is not an unrelated capability, but it is only a small subset of the declared functionality. Because the declared purpose materially overstates the implemented behavior and omits the script’s concrete local-file scanning/upload focus, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

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

md
| 顶级域名(如 `lexiangla.com`) | `{domain}/pages/{entry_id}?company_from={company_from}` | `https://lexiangla.com/pages/abc?company_from=csig` |

**`{company_from}` 获取优先级:**
1. mcp.json `url` 字段中的 `company_from` 参数
2. 若无,使用 `whoami().company.code`

---

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · references/base.md (reported line 54)May include surrounding context.

md
| 顶级域名(如 `lexiangla.com`) | `{domain}/pages/{entry_id}?company_from={company_from}` | `https://lexiangla.com/pages/abc?company_from=csig` |

**`{company_from}` 获取优先级:**
1. mcp.json `url` 字段中的 `company_from` 参数
2. 若无,使用 `whoami().company.code`

---

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The skill instructs the agent to read configuration-derived values from mcp.json to construct links. Access to configuration files is broader than normal task data and can expose internal endpoints, tenant identifiers, or other sensitive connection metadata if the agent is allowed to inspect local config.

Content

Scanner excerpt · references/files.md (reported line 117)May include surrounding context.

md
**返回值**:包含新文件的 `entry_id`,上传完成。按 `references/base.md` 中的**链接生成规则**拼接访问链接返回给用户。

> `{company_from}` 优先从 mcp.json `url` 提取,其次取 `whoami().company.code`。

---

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The instructions direct the agent to read mcp.json to obtain company_from for token-expiry handling. Even though the target value is less sensitive than the token itself, this still normalizes agent access to local credential/config files without an explicit permission boundary, increasing the risk of over-collection or accidental exposure of nearby secrets in the same file.

Content

Scanner excerpt · references/setup.md (reported line 141)May include surrounding context.

当 MCP 返回正常结果但附带过期预警信息时:

  1. 先正常返回本次结果
  2. 读取 mcp.json 中 url 字段里的 company_from 参数值
  3. 在结果末尾附加提醒:
text

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

This repeats the same risky pattern in the expired-token flow: the agent is told to inspect mcp.json for company_from. In context, the file also contains bearer credentials, so allowing routine reads of it expands the blast radius of any prompt-injection, implementation bug, or logging mistake.

Content

Scanner excerpt · references/setup.md (reported line 152)May include surrounding context.

阶段 3:Token 已过期(401 响应)

  1. 不要反复重试
  2. 读取 mcp.json 中 url 字段里的 company_from 参数值
  3. 引导用户续期,原 token 即可恢复,无需重新获取新 token:
text

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The text mandates extracting company_from from the mcp.json URL field and says it cannot be omitted, which encourages direct parsing of a local config file containing secrets. The danger is not the company_from value alone but the instruction pattern that authorizes local secret-file access as part of normal operation.

Content

Scanner excerpt · references/setup.md (reported line 160)May include surrounding context.

https://lexiangla.com/mcp?company_from=<从mcp.json读取的company_from值>

text

> `company_from` 从 mcp.json `url` 字段提取(如 `?company_from=csig` 中的 `csig`),**不能省略**。

### 租户隔离规则

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · references/setup.md (reported line 174)May include surrounding context.

md
| 问题 | 平台 | 解决方案 |
|------|------|---------|
| 连接器未连接 | 内置连接器平台 | 在客户端「集成」页面重新授权 |
| 连接无响应 | 其他平台 | 确认 mcp.json 中 URL 包含 `company_from` 且格式正确 |
| 401 未授权 | 其他平台 | token 过期或租户不匹配,参见上方「AccessToken 生命周期管理」 |
| 参数报错 | 所有平台 | 执行 `get_tool_schema(tool_name="xxx")` 获取最新参数定义 |
| 手动 MCP 与连接器冲突 | 内置连接器平台 | 从 mcp.json 删除 lexiang 手动条目,仅保留连接器 |

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The skill instructs the agent to read company_from from mcp.json URL configuration when constructing user-facing links. Accessing MCP configuration expands the skill's reach into potentially sensitive local config data and creates a path for configuration-derived information to influence outputs, which is unnecessary here because a safer fallback already exists via whoami().company.code. In context, this is somewhat constrained because only one URL parameter is referenced, but it still normalizes config access from prompt instructions and could expose or misuse internal connection metadata.

Content

Scanner excerpt · references/writer.md (reported line 102)May include surrounding context.

md
1. `{domain}` = `whoami()` 返回的 `company.company_domain`
2. 判断 `{domain}` 是否为顶级域名(不含三级前缀,如 `lexiangla.com`):
   - **是**:追加 `?company_from={company_from}`
     - `{company_from}` 优先取 mcp.json `url` 中的 `company_from` 参数
     - 若 mcp.json 中无此参数,取 `whoami()` 返回的 `company.code`
   - **否**(如 `csig.lexiangla.com`):直接使用 `{domain}/pages/{entry_id}`,不追加参数
3. 最终链接:`{domain}/pages/{entry_id}` 或 `{domain}/pages/{entry_id}?company_from=xxx`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This markdown file describes capabilities including document writing, block editing, file upload, and external import, all of which can affect user data and system content. While later lines include an internal safety rule about requiring a user-specified target, the README does not clearly warn users that these actions are state-changing and may alter or overwrite knowledge-base content.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
79% confidence
Finding

The skill advertises broad operational behavior and references multiple external tools and workflows, but it does not declare any explicit tool scope such as allowed-tools or permissions. In an agent environment, missing scope boundaries can let the runtime grant more capabilities than are actually needed, increasing the blast radius if the skill is misrouted, abused, or later extended unsafely.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The activation logic is very broad, triggering on generic terms like '知识库', '个人知识库', or related URL fragments. Overbroad routing can cause this skill to activate in contexts it should not handle, leading the agent to access enterprise knowledge-base tools or credentials when the user may have meant a different product or a generic concept.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The invocation guidance uses ambiguous trigger phrases and broad examples without robust disambiguation checks. In agent systems, ambiguous routing is dangerous because it can invoke sensitive read/write workflows based on weak lexical matches, increasing the chance of unintended data access or writes to the wrong system.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file is written entirely in Chinese, starting with the title at L001, and does not provide any opt-in, alternative language, or explanation that the skill is region- or language-specific. Under the policy rule for natural-language violations, forcing a specific language without user choice is a locale-policy issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation explicitly exposes a delete_text operation that can remove arbitrary text ranges, but it does not warn that the action is destructive, potentially irreversible, or should require explicit user confirmation. In an agent skill context, this increases the chance that an LLM-driven agent will perform unintended destructive edits to a user's knowledge-base content without adequate safeguards.

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 · references/blocks.md (reported line 88)May include surrounding context.

md
Step 1: block_apply_block_attachment_upload
  → 返回 session_id + upload_url

Step 2: curl -X PUT --data-binary "@文件" upload_url
  (HTTP PUT,非 MCP 调用)

Step 3: 在 block_create_block_descendant 中,attachment/image block

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

该 Markdown 文档从标题到正文均仅以中文呈现,未说明这是面向特定中文用户群的区域性文档,也未提供用户可选择的语言或本地化选项。根据规则,强制特定语言而无用户选择或明确合理说明,属于自然语言层面的语言/locale policy 风险。

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly instructs execution of local shell commands and a raw curl PUT upload outside the MCP tool boundary. This expands the agent from using constrained knowledge-base APIs to handling local files and subprocess-like behavior, which increases the risk of unintended local file access, command misuse, and bypass of normal tool safety controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation tells the agent to transmit a local file to a presigned external URL but does not require a privacy notice or explicit confirmation that the selected file may be uploaded off-host. In an agent context, that omission can lead to accidental exfiltration of sensitive local content under the guise of a normal file-management workflow.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The prescribed curl PUT sends local file contents to an external upload URL, creating a direct exfiltration path. Although file upload is part of the feature's purpose, the combination of external transmission and lack of strong consent/validation makes this more dangerous in an agent setting than in ordinary user-operated documentation.

Content

Scanner excerpt · references/files.md (reported line 89)May include surrounding context.

Step 2: HTTP PUT 上传文件内容(curl命令,非 MCP)

⚠️ 这一步不是 MCP 调用,必须用 curl 命令执行 HTTP PUT 请求。

bash
curl -X PUT \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The rollback instructions describe restoring a prior file revision without warning that the current state may be overwritten or replaced. In a content-management environment, this can cause destructive changes, data loss, or rollback to stale content if triggered without an explicit confirmation step.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill describes recursively syncing a local folder to a remote knowledge base but does not clearly warn users that local documents, metadata, and possibly sensitive content will be transmitted off-host. This is dangerous because users may invoke the workflow assuming it is a local-only operation and unintentionally expose confidential files to a third-party service.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

The documentation instructs use of npx ts-node without pinning a specific package version, which can cause execution of an unexpected or newly published dependency version at runtime. In a workflow that scans local folders and prepares uploads to a remote service, this increases supply-chain risk because a compromised or changed package could access sensitive local files before upload.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documented three-step upload flow includes an HTTP PUT to a pre-signed URL, but the user-facing text does not explicitly disclose that file contents are sent over the network to external storage. This omission can lead to unintended disclosure of sensitive files because the transfer step may be less obvious than the MCP calls surrounding it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document instructs users to upload Markdown files from a local system to a remote knowledge base, but it provides no warning to review the files for secrets, personal data, or other sensitive content before transmission. In a knowledge-base integration skill, this omission increases the risk of accidental data exfiltration because users may treat the workflow as routine and upload internal documents without considering sensitivity.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/test_upload_files.py:28