Back to skill

Security audit

阿里云云效创建MR+发布+通知(全可配置)

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent with its stated purpose, but it can immediately create merge requests and trigger deployment pipelines from LLM-parsed natural language without confirmation.

Review before installing. Use only a least-privilege Yunxiao token, preferably scoped away from production pipelines; restrict or remove default repo and pipeline IDs; validate/allowlist repositories, branches, and pipeline IDs; require explicit confirmation before MR creation or deployment; and configure the webhook only to a trusted endpoint. The manifest should also be fixed to point to the shipped Python file before use.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
ailiyun_yunxiao_mr_deploy.py:79
Finding

Unvalidated LLM output controls privileged MR creation and pipeline execution

Content
View full analysis
1: lines = "\n".join([ f" · {p['pipelineName']} (ID: {p['pipelineId']})" for p in matched ]) return lines flow_id = str(matched[0]["pipelineId"]) pipeline_display = ( f"{matched[0]['pipelineName']} (ID: {flow_id})" ) else: pipeline_display = f"Pipeline ID: {flow_id}" data, code = run_publish(flow_id) ``` ### Technical Analysis The handler embeds the user ...[truncated 2476 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
skills.json:5
Finding

Package manifest references a nonexistent entrypoint

Content
View full analysis
Remediation
View remediation
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Tainted flow: 'CONFIG' from os.environ.get (line 13, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The webhook URL is taken directly from an environment variable and used as the destination of an outbound POST with operational content. If that variable is misconfigured or attacker-controlled, the skill can exfiltrate sensitive workflow details and notifications to an arbitrary external endpoint, and the broad exception handler hides misuse or failures.

Content

Scanner excerpt · ailiyun_yunxiao_mr_deploy.py (reported line 113)May include surrounding context.

python
"text": {"content": f"【云效通知】\n{content}"}
    }
    try:
        requests.post(CONFIG["WECOM_WEBHOOK"], json=data, timeout=5)
    except:
        pass

Tainted flow: 'url' from os.environ.get (line 277, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · ailiyun_yunxiao_mr_deploy.py (reported line 133)May include surrounding context.

python
"page": 1,
    }
    try:
        resp = requests.get(url=url, headers=HEADERS, json=request_body, timeout=15)
        if resp.status_code != 200:
            send_wecom(f"❌ 查询仓库列表失败:{resp.status_code} - {resp.text}")
            return {}

Tainted flow: 'url' from os.environ.get (line 237, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · ailiyun_yunxiao_mr_deploy.py (reported line 175)May include surrounding context.

python
"triggerAIReviewRun": False,
        "workItemIds": []
    }
    resp = requests.post(url, json=data, headers=HEADERS, timeout=15)
    return resp.json(), resp.status_code, url

Tainted flow: 'url' from os.environ.get (line 237, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · ailiyun_yunxiao_mr_deploy.py (reported line 185)May include surrounding context.

python
f"https://{CONFIG['DOMAIN']}/oapi/v1/codeup/organizations/{CONFIG['ORGANIZATION_ID']}"
        f"/repositories/{repo_id}/changeRequests/{mr_id}"
    )
    resp = requests.get(url, headers=HEADERS, timeout=10)
    return resp.json() if resp.status_code == 200 else None

Tainted flow: 'url' from os.environ.get (line 277, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · ailiyun_yunxiao_mr_deploy.py (reported line 209)May include surrounding context.

python
if search_name:
            params["pipelineName"] = search_name
        try:
            resp = requests.get(url, headers=HEADERS, params=params, timeout=15)
            if resp.status_code != 200:
                break
            batch = resp.json()

Tainted flow: 'url' from os.environ.get (line 237, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · ailiyun_yunxiao_mr_deploy.py (reported line 238)May include surrounding context.

python
# ===================== 触发发布流水线 =====================
def run_publish(flow_id):
    url = f"https://{CONFIG['DOMAIN']}/oapi/v1/flow/pipelines/{flow_id}/runs"
    resp = requests.post(url, headers=HEADERS, timeout=15)
    return resp.json(), resp.status_code

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

User input is interpolated directly into the LLM prompt that decides whether to create MRs, query MRs, or trigger deployments. An attacker can craft text that manipulates the parser into extracting a different action, repo, branch, or flow ID than intended, which is especially dangerous because downstream operations are state-changing and immediate.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

技能说明没有显式警告用户该技能会触发真实部署并向外部 webhook 发送通知,用户可能将其当作普通查询/助手能力使用。由于其可调用发布流水线并将结果推送到外部地址,缺少风险披露会放大误操作、信息外发和社会工程利用的风险。

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

发布触发描述存在歧义,尤其“线上发布”这类过于宽泛的示例,可能让模型在缺少关键上下文时直接触发默认流水线。该技能的上下文明确包含真实部署和外部通知能力,因此误触发的后果比普通只读技能更严重,可能造成生产环境变更或错误发布。

Content

No source excerpt is available for this finding.

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.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill sends raw user instructions to an LLM for intent parsing, which is an external data disclosure path not clearly bounded in the declared operational behavior. User requests may contain repository names, branch names, MR identifiers, or deployment intent that could be sensitive in some environments.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The skill transmits operational messages to an external webhook service. Those messages can include repository names, MR URLs/IDs, error responses, and deployment events, which may leak internal engineering metadata to third parties if the webhook is not tightly controlled.

Content

Scanner excerpt · ailiyun_yunxiao_mr_deploy.py (reported line 113)May include surrounding context.

python
"text": {"content": f"【云效通知】\n{content}"}
    }
    try:
        requests.post(CONFIG["WECOM_WEBHOOK"], json=data, timeout=5)
    except:
        pass

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · ailiyun_yunxiao_mr_deploy.py (reported line 175)May include surrounding context.

python
"triggerAIReviewRun": False,
        "workItemIds": []
    }
    resp = requests.post(url, json=data, headers=HEADERS, timeout=15)
    return resp.json(), resp.status_code, url

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

A deployment pipeline can be triggered immediately based on parsed user input, with no confirmation step, no secondary authorization, and no user-facing warning about production impact. In a natural-language interface, this is especially dangerous because misclassification, prompt injection, or ambiguous wording can cause unintended releases.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

这些创建 MR 的自然语言触发示例非常宽泛,且与日常表述高度重叠,容易在普通对话中被误识别为执行指令。由于该技能会发起真实代码协作操作,缺少明确确认门槛会导致误建 MR、错误分支合并请求或在错误仓库上执行操作。

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger list contains very broad phrases like "发布", "上线", and even "创建MR" that are common in normal engineering conversation. In a skill that can create merge requests, trigger deployments, and send notifications, overly generic activation phrases increase the chance of accidental invocation or prompt routing to a high-impact automation path without sufficient user intent verification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

MR creation is executed immediately once the LLM labels the request as create_mr, without a preview or confirmation of the resolved repository and branches. This can lead to unintended merge requests, noisy workflow automation, or abuse if the intent parser is manipulated.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.