Back to skill

Security audit

Promotion Apply Skills

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its banner-promotion purpose, but it can change business promotions and upload assets while using unsafe runtime package installation and unrestricted image downloading.

Install only if you trust the MWS environment and are comfortable with this skill making real banner promotion changes, adding promotion admins, and uploading images. Before use, remove runtime pip installation, pin dependencies, restrict remote image downloads to approved domains or local files, and handle NOS tokens in a private temporary directory with immediate cleanup.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/resize_cover.py:35
Finding

Unrestricted Remote Image Retrieval Enables Server-Side Request Forgery

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/resize_cover.py:12
Finding

Automatic Installation of Unpinned Python Dependencies at Runtime

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/image-upload-nos.md:96
Finding

NOS Upload Token Can Remain in a Predictable Plaintext Working-Directory File

Content
View full analysis
. 6. Then process the next image. ``` ### Technical Analysis The workflow permits a sensitive NOS upload token to be written to a predictable relative path named `download.txt`. It deletes a previous file before requesting a new token, but it does not: - Create a private working directory. - Require restrictive file permissions. - Use a securely created unique temporary file. - Remove the token file immediately after upload. - Install a cleanup trap for failures and interruptions. - Prevent other local processes from observing or replacing the predictable path. The token response may therefore remain on disk after use and may inher ...[truncated 1589 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad operational skill for 灵渠 Banner promotion lifecycle tasks, including creation, querying, copying, preemption/cancel-preemption, status updates, modification, creative handling, and material association. The supplied code does not perform those actions. It only parses promotion-detail JSON, lists available delivery resource options, infers a likely resource selection, normalizes selected fields, and prints suggested external commands for validating a standard resource and extracting templates for positions such as discovery-page banner endpoints. This is related to banner creative/material preparation, so it is in-domain, but it is only a narrow helper utility rather than the described end-to-end banner promotion skill. Therefore the description materially overstates the implemented capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about business operations for banner promotion management in Lingqu, including create/query/copy/modify/status/material workflows. The supplied code does none of that. Instead, it is an image-processing utility that fetches an image from a URL or local path, resizes and crops it to target dimensions, and writes an output JPEG. This is a materially different primary purpose and introduces undeclared capabilities such as network image retrieval, filesystem image processing, and package installation. Therefore the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向 Banner 推广配置与管理的 skill,涵盖创建、查询、复制、修改、预占/取消预占、状态修改、创意和物料关联等完整业务能力。但给定代码仅是一个离线分析脚本:读取资源列表 JSON,整理默认跳转链接、角标、作者等资源元数据,并在缺失时输出提示。它没有任何 Banner 推广对象的创建、查询、复制、修改、状态切换或素材关联逻辑,也没有体现声明中的触发场景。虽然提取“默认角标/跳转链接”可能可作为 Banner 配置的辅助步骤,但这只是支持性子功能,无法代表声明的主要用途,因此描述与实际行为存在明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description describes an operational advertising skill for managing Lingqu banner promotions and related creative/material workflows. The supplied code does none of those actions. It is a local analysis/reporting utility that parses JSON input and summarizes template schema fields for display. There are no API calls, no banner promotion CRUD/state operations, no reservation handling, and no material association logic. This is a materially different primary purpose and capability set, so the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared skill is about managing banner promotions and related creative/material operations in a business workflow. The actual code only validates image dimensions, optionally downloading an image from a URL, and does not implement any banner configuration, CRUD operations, status changes, reservation logic, or material-linking behavior. While image validation could theoretically support banner asset checks, this chunk’s primary purpose is materially different and far narrower than the declared skill.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
reative` 插入失败、`name ... null`,这是 `creative.name` 缺失,不是数据库问题。立即停止原 payload 重试,按 [references/creative-dynamic-material.md](references/creative-dynamic-material.md

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
reative` 插入失败、`name ... null`,这是 `creative.name` 缺失,不是数据库问题。立即停止原 payload 重试,按 [references/creative-dynamic-material.md](references/creative-dynamic-material.md

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
reative` 插入失败、`name ... null`,这是 `creative.name` 缺失,不是数据库问题。立即停止原 payload 重试,按 [references/creative-dynamic-material.md](references/creative-dynamic-material.md

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
reative` 插入失败、`name ... null`,这是 `creative.name` 缺失,不是数据库问题。立即停止原 payload 重试,按 [references/creative-dynamic-material.md](references/creative-dynamic-material.md

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
reative` 插入失败、`name ... null`,这是 `creative.name` 缺失,不是数据库问题。立即停止原 payload 重试,按 [references/creative-dynamic-material.md](references/creative-dynamic-material.md

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

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

Content

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

}'

text

`plan-pack-resource-list` 的资源 ID 参数必须叫 `resourceIds`(复数,字符串,多个 ID 用英文逗号拼接),禁止写 `resourceId`。如果看到错误 `Required String parameter 'resourceIds' is not present`,不要继续换 HTTP/curl 或猜其它字段,直接把参数从 `resourceId` 改为 `resourceIds` 并通过 `mws link plan-pack-resource-list` 重试:

```bash
mws link plan-pack-resource-list --env ${MWS_ENV} --params '{"resourceType":"album","resourceIds":"382794761"}' --format json

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

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

Content

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

}'

text

`plan-pack-resource-list` 的资源 ID 参数必须叫 `resourceIds`(复数,字符串,多个 ID 用英文逗号拼接),禁止写 `resourceId`。如果看到错误 `Required String parameter 'resourceIds' is not present`,不要继续换 HTTP/curl 或猜其它字段,直接把参数从 `resourceId` 改为 `resourceIds` 并通过 `mws link plan-pack-resource-list` 重试:

```bash
mws link plan-pack-resource-list --env ${MWS_ENV} --params '{"resourceType":"album","resourceIds":"382794761"}' --format json

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

The script invokes a shell to install packages at runtime, which creates an unnecessary command-execution and supply-chain risk during normal image processing. Even though the command string is mostly static, it still executes external code from package repositories and depends on the runtime environment, making behavior non-deterministic and unsafe for a banner-processing helper.

Content

Scanner excerpt · scripts/resize_cover.py (reported line 17)May include surrounding context.

python
from PIL import Image
except ImportError:
    print("Installing Pillow...", file=sys.stderr)
    os.system(f"{sys.executable} -m pip install Pillow requests -q")
    from PIL import Image

try:

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

This second shell-based package installation repeats the same unsafe pattern: the script automatically fetches and installs code at execution time instead of relying on pre-provisioned dependencies. That exposes the environment to unintended package execution, repository tampering, and operational surprises unrelated to the stated image-resize function.

Content

Scanner excerpt · scripts/resize_cover.py (reported line 24)May include surrounding context.

python
import requests
except ImportError:
    print("Installing requests...", file=sys.stderr)
    os.system(f"{sys.executable} -m pip install requests -q")
    import requests

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

The script invokes a shell command to install Pillow at runtime using os.system. Even though the command string is not directly user-controlled, executing package installation as a side effect of validation is dangerous because it enables unreviewed code download/execution from package indexes and expands the tool's privileges unexpectedly.

Content

Scanner excerpt · scripts/validate_image_size.py (reported line 16)May include surrounding context.

python
from PIL import Image
except ImportError:
    print("Installing Pillow...", file=sys.stderr)
    os.system(f"{sys.executable} -m pip install Pillow -q")
    from PIL import Image

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This os.system call installs requests dynamically at runtime, again causing the validator to execute external package-management commands as a side effect. In combination with the URL-loading feature, this broadens the attack surface and can result in execution of untrusted code or supply-chain compromise if the environment or package source is tampered with.

Content

Scanner excerpt · scripts/validate_image_size.py (reported line 26)May include surrounding context.

python
import requests
        except ImportError:
            print("Installing requests...", file=sys.stderr)
            os.system(f"{sys.executable} -m pip install requests -q")
            import requests
        response = requests.get(path_or_url, timeout=30)
        response.raise_for_status()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documents extensive shell, file, and network-capable operations but does not declare any explicit tool scope such as allowed-tools or permissions. In an agent runtime, that omission weakens least-privilege boundaries and can allow the skill to be invoked with broader capabilities than users or reviewers expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases include broad generic terms such as 查询/创建/修改/素材 that can overlap with normal conversation and unrelated requests. Overbroad activation increases the chance that the skill is invoked unexpectedly for sensitive write actions, especially because the skill can create, modify, upload, and change status in external systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill instructs retrieval of a backend NOS token and direct object-storage upload without a clear user-facing warning, approval gate, or token-handling constraints. In a skill that processes user-supplied URLs and local files, this raises the risk of credential misuse, unauthorized uploads, or accidental exposure of sensitive upload capability.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · SKILL.md (reported line 183)May include surrounding context.

md
| `name` | 最终提交推广名称,格式为 `【内容大类/版权类型/战略类型/投放资源标签】推广基础名称 –【二级部门】`,长度不超过 50 |
| `projectName` | 项目名称,使用用户真实项目名 |
| `projectOwner` | 项目负责人邮箱前缀,不传完整邮箱;优先取当前会话真实发起人或当前登录用户。只有 `grp.`/机器人执行且无法确认真实发起人时才问用户 |
| `creatorDept` | AI VO 不直接传该字段;服务端从推广名称末尾 `–【二级部门】` 解析并写入。本部门龙虾/运营审核机器人场景默认 `内容运营部`;非 `grp.` 执行身份可从 `pms-login-status.data.depList[level=2].name` 取。其它 `grp.` 场景无法确认本部门时才问真实二级部门 |
| 投放端 | 用户选择的端,内部转换为 `relatedPositionCodes` |
| `startTime` / `endTime` | `yyyy-MM-dd HH:mm:ss`;只给日期时按自然日闭区间,开始日 00:00:00,结束日 23:59:59;同一天小时段不拆,跨自然日才可能按天拆分,最多 7 天;拆分前必须让用户在“拆分/不拆分”中二选一 |
| `contentCategory` | 内容大类 code |

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · SKILL.md (reported line 341)May include surrounding context.

md
| `name` | 最终提交推广名称,格式为 `【内容大类/版权类型/战略类型/投放资源标签】推广基础名称 –【二级部门】`,长度不超过 50 |
| `projectName` | 项目名称,使用用户真实项目名 |
| `projectOwner` | 项目负责人邮箱前缀,不传完整邮箱;优先取当前会话真实发起人或当前登录用户。只有 `grp.`/机器人执行且无法确认真实发起人时才问用户 |
| `creatorDept` | AI VO 不直接传该字段;服务端从推广名称末尾 `–【二级部门】` 解析并写入。本部门龙虾/运营审核机器人场景默认 `内容运营部`;非 `grp.` 执行身份可从 `pms-login-status.data.depList[level=2].name` 取。其它 `grp.` 场景无法确认本部门时才问真实二级部门 |
| 投放端 | 用户选择的端,内部转换为 `relatedPositionCodes` |
| `startTime` / `endTime` | `yyyy-MM-dd HH:mm:ss`;只给日期时按自然日闭区间,开始日 00:00:00,结束日 23:59:59;同一天小时段不拆,跨自然日才可能按天拆分,最多 7 天;拆分前必须让用户在“拆分/不拆分”中二选一 |
| `contentCategory` | 内容大类 code |

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · SKILL.md (reported line 432)May include surrounding context.

md
| `name` | 最终提交推广名称,格式为 `【内容大类/版权类型/战略类型/投放资源标签】推广基础名称 –【二级部门】`,长度不超过 50 |
| `projectName` | 项目名称,使用用户真实项目名 |
| `projectOwner` | 项目负责人邮箱前缀,不传完整邮箱;优先取当前会话真实发起人或当前登录用户。只有 `grp.`/机器人执行且无法确认真实发起人时才问用户 |
| `creatorDept` | AI VO 不直接传该字段;服务端从推广名称末尾 `–【二级部门】` 解析并写入。本部门龙虾/运营审核机器人场景默认 `内容运营部`;非 `grp.` 执行身份可从 `pms-login-status.data.depList[level=2].name` 取。其它 `grp.` 场景无法确认本部门时才问真实二级部门 |
| 投放端 | 用户选择的端,内部转换为 `relatedPositionCodes` |
| `startTime` / `endTime` | `yyyy-MM-dd HH:mm:ss`;只给日期时按自然日闭区间,开始日 00:00:00,结束日 23:59:59;同一天小时段不拆,跨自然日才可能按天拆分,最多 7 天;拆分前必须让用户在“拆分/不拆分”中二选一 |
| `contentCategory` | 内容大类 code |

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This markdown file is written as operational instructions entirely in Chinese, beginning with the section header at L003, and nowhere offers users or operators a language/locale choice. Under the policy rule, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reference states '本 skill 不修改已有创意' at L016, but immediately instructs saving via promotion-update-creative, which is an update operation on promotion materials. Later guidance also allows retaining creative.id for existing creatives and modifying entries in the existing promotionAliasCreativeList, which contradicts the claim that existing creatives are not modified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

L552 says the skill '仅支持按当前模板重新保存一份推广物料' and does not modify existing creatives, yet L560 explicitly says that when a position alias already has multiple creatives, the operator should read the original promotionAliasCreativeList, add/delete/modify corresponding items, and submit the whole list. That is an active contradiction between stated intent and required behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.