Back to skill

Security audit

Devops Pipeline Management

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its DevOps pipeline-management purpose, but it can create, run, update, and delete real pipelines while sending and logging sensitive pipeline data with weak safety controls.

Install only if you intend to let this skill operate real DevOps pipelines. Before use, pin DEVOPS_BFF_URL to the trusted HTTPS DevOps host, avoid captured/shared logs or remove verbose logging, do not use delete until confirmation is added, and be careful with non-interactive creation because one script can auto-confirm and auto-run pipelines.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/client.py:17
Finding
Unrestricted API Destination Can Receive User Identity and Sensitive Pipeline Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/client.py:17-58` **Vulnerability Type**: Unvalidated outbound network destination and sensitive-data disclosure **Risk Level**: High ### Vulnerable Code ```python def __init__(self, domain_account: Optional[str] = None, bff_url: Optional[str] = None): self.domain_account = domain_account or os.getenv('DEVOPS_DOMAIN_ACCOUNT') self.bff_url = bff_url or os.getenv('DEVOPS_BFF_URL') if not self.domain_account: raise ValueError("Domain account is required. Set DEVOPS_DOMAIN_ACCOUNT.") if not self.bff_url: raise ValueError("BFF URL is required. Set DEVOPS_BFF_URL environment variable.") self.session = requests.Session() self.session.headers.update({'Content-Type': 'application/json'}) def _request(self, method: str, endpoint: str, data: Optional[Dict] = None, params: Optional[Dict] = None) -> Dict[str, Any]: url = f"{self.bff_url}{endpoint}" headers = { 'X-User-Account': self.domain_account } try: if method.upper() == 'GET': response = self.session.get(url, params=params, headers=headers) elif method.upper() == 'POST': response = self.session.post(url, json=data, headers=headers) elif method.upper() == 'DELETE': response = self.session.delete(url, headers=headers) ``` ### Technical Analysis The client obtains the API base URL directly from the `DEVOPS_BFF_URL` environment variable and concatenates it with privileged API endpoints. It does not parse or validate the URL's scheme, hostname, port, user-information component, or resolved network address. Every request automatically includes the user's domain account in `X-User-Account`. POST requests can additionally contain complete pipeline configurations, task parameters, repository URLs, branch information, package metadata, deployment settings, and execution parameters. Outbound network access is necessary for t ...[truncated 2057 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the base URL with `urllib.parse.urlsplit()` before creating the client. 2. Require the `https` scheme and reject plaintext HTTP. 3. Maintain an explicit allowlist of approved DevOps API hostnames. 4. Reject URLs containing user information, fragments, unexpected paths, or unauthorized ports. 5. Resolve the hostname and reject loopback, link-local, multicast, private, or otherwise prohibited addresses unless an explicitly approved internal endpoint requires them. 6. Normalize the configured base URL and safely join fixed API paths rather than using unrestricted string concatenation. 7. Disable automatic redirects for sensitive requests or validate every redirect destination against the same allowlist. 8. Configure connection and read timeouts for all requests. 9. Use a scoped authentication mechanism rather than treating a caller-supplied account header as sufficient authorization. 10. Document the exact approved destination and fail closed when validation cannot be completed. A hardened implementation should resemble: ```python from urllib.parse import urlsplit import ipaddress import socket APPROVED_HOSTS = {"one-dev.iflytek.com"} parsed = urlsplit(self.bff_url) if parsed.scheme != "https": raise ValueError("DEVOPS_BFF_URL must use HTTPS") if parsed.hostname not in APPROVED_HOSTS: raise ValueError("DEVOPS_BFF_URL host is not approved") if parsed.username or parsed.password or parsed.fragment: raise ValueError("Invalid DEVOPS_BFF_URL") ``` Requests should also use explicit timeouts and constrained redirects: ```python response = self.session.post( url, json=data, headers=headers, timeout=(5, 30), allow_redirects=False ) ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/client.py:38
Finding
Unconditional Logging Exposes Account Information and Complete API Payloads<![CDATA[ ## Vulnerability Details **File Location**: `scripts/client.py:38-75` **Vulnerability Type**: Sensitive information exposure through logs **Risk Level**: Medium ### Vulnerable Code ```python # 打印请求信息(调试用) print("\n" + "=" * 60) print(f"[Request] {method.upper()} {url}") print("-" * 60) print("Headers:") for k, v in headers.items(): print(f" {k}: {v}") if params: print("-" * 60) print(f"Query Params: {json.dumps(params, ensure_ascii=False)}") if data: print("-" * 60) print(f"Body: {json.dumps(data, indent=2, ensure_ascii=False)}") print("=" * 60 + "\n") # 打印响应信息(调试用) print("=" * 60) print(f"[Response] Status: {response.status_code}") print("-" * 60) print("Response Headers:") for k, v in response.headers.items(): print(f" {k}: {v}") print("-" * 60) try: resp_json = response.json() print(f"Response Body:\n{json.dumps(resp_json, indent=2, ensure_ascii=False)}") except Exception: print(f"Response Body (text):\n{response.text}") print("=" * 60 + "\n") ``` ### Technical Analysis The shared HTTP client prints request headers, query parameters, complete request bodies, response headers, and complete response bodies for every API invocation. This is not protected by a debug setting and is therefore active during normal use. The request header contains the user's domain account. Request and response payloads may include repository information, source configuration, task parameters, execution remarks, custom parameters, deployment details, workspace information, console logs, and credential identifiers. The generic serializer does not redact keys such as `Authorization`, `token`, `password`, `secret`, `credentialId`, or `privateKey`. Because stdout and stderr are commonly captured by CI systems, Agent frameworks, terminal recording, support bundles, and centralized log collectors, the code creates additional persistent copies of information that only needed to be transmitted to the DevOps API. Response-header logging ...[truncated 1660 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable detailed request and response logging by default. 2. Introduce an explicit debug option that users must intentionally enable. 3. Use Python's `logging` module instead of direct `print()` calls. 4. Never log authentication or identity headers at their original values. 5. Recursively redact sensitive keys, including: - `authorization` - `cookie` - `set-cookie` - `token` - `password` - `secret` - `credential` - `credentialId` - `privateKey` - `accessKey` - `apiKey` 6. Log only the HTTP method, approved hostname, endpoint name, status code, duration, and a sanitized request ID during normal operation. 7. Truncate large responses and avoid logging raw console output or arbitrary response text. 8. Sanitize control characters before writing remotely supplied text to a terminal. 9. Document that task and pipeline configuration must reference secret stores rather than contain plaintext secrets. 10. Add automated tests confirming that representative credentials cannot appear in logs. For example: ```python SENSITIVE_HEADERS = { "authorization", "cookie", "set-cookie", "x-user-account" } safe_headers = { key: "[REDACTED]" if key.lower() in SENSITIVE_HEADERS else value for key, value in headers.items() } ``` A recursive payload-redaction function should be applied before any structured object is logged. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:288
Finding
Irreversible Pipeline Deletion Is Performed Without Confirmation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py:288-294` **Related Sink**: `scripts/pipeline_ops.py:131-137` **Vulnerability Type**: Missing authorization-intent confirmation for a destructive operation **Risk Level**: Medium ### Vulnerable Code ```python elif command == 'delete': if len(sys.argv) < 3: print("Error: pipeline_id is required", file=sys.stderr) sys.exit(1) result = client.delete_pipeline(sys.argv[2]) print(json.dumps(result, indent=2, ensure_ascii=False)) ``` The invoked operation immediately reaches the deletion endpoint: ```python def delete_pipeline(self, pipeline_id: str) -> Dict[str, Any]: """ 删除流水线 接口: POST /pipeline/delete?pipelineId={pipelineId} """ return self._request('POST', f'/api/ai-bff/rest/openapi/pipeline/delete?pipelineId={pipeline_id}') ``` ### Technical Analysis The `delete` CLI command accepts a pipeline identifier and immediately sends a deletion request. It does not: - Query and display the pipeline identity before deletion. - Confirm that the target is the pipeline intended by the user. - Ask for interactive approval. - Require an explicit non-interactive acknowledgment such as `--yes`. - Check whether the pipeline is running. - Enforce the deletion-confirmation constraint described by the Skill documentation. This is particularly significant in an AI Agent context, where an ambiguous request, incorrectly extracted identifier, stale context, or prompt-injected value could be converted into an irreversible API call. The affected action is within the declared functionality, but the lack of an intent checkpoint removes a minimum safety boundary for destructive operations. There is also documentation inconsistency: `references/pipeline-delete.md` says that the OpenAPI deletion interface is not confirmed and describes an expected `DELETE /rest/openapi/pipeline/{pipelineId}` operation, while the implementation uses `POST .../pipeline/delete?pipelineI ...[truncated 1313 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Query the pipeline before deletion and display its name, workspace, ID, owner, and execution state. 2. Require interactive confirmation that includes the exact pipeline name or ID. 3. For non-interactive automation, require a deliberate `--yes` or `--confirm <pipeline_id>` argument. 4. Refuse deletion when the pipeline is running unless it has first been explicitly cancelled and its state rechecked. 5. Validate the identifier format before making the request. 6. Reconcile the implementation with the authoritative API specification before enabling deletion. 7. Use the documented HTTP method and pass identifiers through structured parameters rather than interpolating them into the endpoint string. 8. Ensure the backend independently enforces authorization and records an immutable audit event. 9. Consider a soft-delete or recoverable retention period where supported. 10. Add tests proving that deletion cannot occur without explicit confirmation. A suitable interactive flow would be: ```python pipeline = client.get_pipeline_detail(pipeline_id) print(f"Pipeline to delete: {pipeline_name} ({pipeline_id})") confirmation = input(f"Type the pipeline ID '{pipeline_id}' to confirm deletion: ") if confirmation != pipeline_id: print("Deletion cancelled") sys.exit(1) result = client.delete_pipeline(pipeline_id) ``` Non-interactive use should fail closed unless an explicit confirmation flag is present. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (175)

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

Critical
Category
Data Flow
Content
}

    print(f"正在获取模板详情: {template_id}")
    response = requests.get(url, params={"id": template_id}, headers=headers)
    result = response.json()

    if result.get("success") and result.get("code") == "200":
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
print(f"  流水线名称: {pipeline_data['pipeline']['name']}")
    print(f"  空间ID: {pipeline_data['pipeline']['spaceId']}")

    response = requests.post(url, json=pipeline_data, headers=headers)
    result = response.json()

    print(f"\n保存API响应:")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The declared description presents a broad pipeline lifecycle management expert, including workspace search, pipeline CRUD, execution query/cancel, and template operations. This code chunk is much narrower: it is specifically a pipeline creation wizard that creates a pipeline from a template and can immediately execute it. It does include supporting calls to list workspaces and query templates, but these serve the creation flow rather than comprehensive management. Important declared capabilities are absent from the supplied code, notably pipeline querying/updating/deleting, execution cancellation, and execution status/log retrieval. Additionally, the implementation has behavior not suggested by the description: it hardcodes a default GITEE repository URL/branch/work path and, despite prompting for template selection, ultimately forces selection of the first template. Therefore the code does not accurately represent the full declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description says the skill handles the complete lifecycle of pipelines, explicitly including execution and cancellation, execution record/detail queries, and template management limited to querying templates and creating pipelines from templates. The supplied code mainly covers pipeline CRUD/listing and workspace queries, which do align. However, it does not contain methods to execute or cancel pipelines, nor a clear general-purpose execution management implementation matching the declared capability; only a console log fetch and one method misleadingly named get_pipeline_list that actually queries execution records for a specific pipeline. In addition, the code includes several materially undeclared capabilities: saving/editing pipeline templates, querying code repositories and branches, checking repo token status, and fetching image tags/package versions. These go beyond the declared scope enough to constitute a description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a specialized DevOps pipeline management skill, but the supplied code chunk contains only general-purpose terminal input utilities (`prompt_choice`, `prompt_input`, and `confirm`). These functions do not access workspaces, pipelines, executions, templates, APIs, or platform resources, and they do not implement any of the listed core capabilities or trigger scenarios. While such utilities could support a larger pipeline tool, this code chunk by itself materially differs from the declared primary purpose.

Vague Triggers

High
Confidence
98% confidence
Finding
The trigger keywords include extremely generic terms like “新建” and “创建”, which can match many unrelated user requests and cause unintended invocation of a pipeline-creation skill. In a DevOps context, accidental activation can lead to creation of infrastructure or CI/CD artifacts the user did not intend, increasing the risk of unauthorized changes, misconfigurations, or follow-on execution if paired with permissive downstream flows.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## 预期API接口

- **路径**: DELETE /rest/openapi/pipeline/{pipelineId}
- **方法**: DELETE

## 请求参数
Confidence
88% confidence
Finding
The skill documents and encourages a destructive DELETE operation against a pipeline resource without showing any safety gating such as explicit user confirmation, authorization checks, validation of the target identifier, or precondition checks beyond a note in prose. Because this is an agent skill for DevOps pipeline management, an LLM or automation layer could operationalize this into real deletion of CI/CD configuration, making accidental or unauthorized destructive actions more likely.

Missing User Warnings

High
Confidence
95% confidence
Finding
The document states that updates are full replacements and omitted fields will be cleared, but it does not present a prominent explicit warning about data loss risk at the point of action. In the DevOps pipeline context, this can delete stages, tasks, triggers, or source settings and disrupt build, test, or deployment workflows, potentially causing outages or weakening delivery controls.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 请求

```
DELETE /rest/openapi/pipeline/source/delete?sourceId={sourceId}&pipelineId={pipelineId}
```

### 响应
Confidence
84% confidence
Finding
The documented interface exposes a destructive DELETE operation driven entirely by user-supplied identifiers in the query string, with no mention of authorization, ownership checks, anti-CSRF protections, or confirmation safeguards. In a DevOps pipeline management skill, this is more dangerous because an agent or user could be induced to delete pipeline sources by parameter manipulation, causing build disruption, supply-chain tampering, or loss of repository/package linkage.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
GET    /rest/openapi/pipeline/template/getPipTemplateById
POST   /rest/openapi/pipeline/template/queryNormalPipTemplatePage
POST   /rest/openapi/pipeline/template/copyPipTemplate
DELETE /rest/openapi/pipeline/template/delPipTemplate
```

### 场景4: 查询信息
Confidence
90% confidence
Finding
The documented DELETE template endpoint is a high-risk destructive operation, and in this skill context an agent could be induced to pass attacker-chosen identifiers and delete valuable pipeline templates. Because template deletion changes system state and may disrupt CI/CD workflows at scale, parameter abuse here has stronger consequences than in a read-only skill.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
})
  }

  return rules
}
```
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Missing User Warnings

High
Confidence
99% confidence
Finding
In non-interactive mode, `confirm()` returns `True` on EOF, which means save and run confirmations are implicitly approved without explicit operator consent. In this skill, those confirmations gate remote state-changing operations against the DevOps platform, so unattended execution can create and immediately run pipelines unexpectedly.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest says this skill covers workspace management and template management, including querying workspaces, querying pipeline templates, and creating pipelines from templates. However, the README documents only pipeline list/detail/create/run/cancel/delete and execution-detail commands, with no documented workspace or template-related operations, indicating a mismatch between the claimed skill scope and the behavior/interface presented here.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger phrases are overly broad for sensitive operations like run and delete, and they do not require clear identification of the target pipeline or sufficient conversational context. In an agent setting, this can cause the skill to activate on ambiguous user input and perform actions against the wrong pipeline, especially because this skill manages real DevOps resources with execution and deletion capabilities.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The README shows automatic execution of delete operations without an immediate warning or required confirmation at the point where users are told how the trigger works. For a skill that can delete pipelines, documenting direct activation without confirmation normalizes unsafe behavior and increases the risk of accidental destructive actions against user assets.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documents capabilities that require environment access, file reads, and network calls, but it does not declare any explicit tool scope or permission boundaries. In an agent setting, missing least-privilege constraints can let the skill invoke broader capabilities than intended, increasing the blast radius if the skill is misused or prompt-injected.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This markdown file contains core operational instructions in Chinese beginning at the overview section, and the rest of the skill documentation continues in that language. Because the skill does not explicitly offer the user a language/locale choice or justify a region-specific language restriction, it creates a natural-language policy concern for forced locale usage.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# 添加软链接(可选:使用 devops-pipeline 作为命令名)
sudo ln -s $(pwd)/scripts/main.py /usr/local/bin/devops-pipeline

# 使用
devops-pipeline --help      # 需要创建符号链接
Confidence
84% confidence
Finding
The documentation instructs users to run a command with sudo to create a symlink under /usr/local/bin. Even though the example is optional, encouraging privileged shell execution in a skill increases risk because path manipulation or copied commands can have host-wide effects if modified, especially in adversarial or poorly reviewed contexts.

External Transmission

Medium
Category
Data Exfiltration
Content
**场景: 取消错误的部署**
```bash
curl -X POST "https://api.example.com/rest/openapi/pipeline/cancel" \
  -H "Content-Type: application/json" \
  -H "X-User-Account: your_domain_account" \
  -d '{"pipelineLogId": 10001}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
**场景: 取消错误的部署**
```bash
curl -X POST "https://api.example.com/rest/openapi/pipeline/cancel" \
  -H "Content-Type: application/json" \
  -H "X-User-Account: your_domain_account" \
  -d '{"pipelineLogId": 10001}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
**场景: 取消错误的部署**
```bash
curl -X POST "https://api.example.com/rest/openapi/pipeline/cancel" \
  -H "Content-Type: application/json" \
  -H "X-User-Account: your_domain_account" \
  -d '{"pipelineLogId": 10001}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The description says the skill should be used for creating new pipelines and CI configurations, but it does not sharply distinguish this from other CI-related tasks, making routing ambiguous. In an operational DevOps environment, ambiguous activation criteria can cause the wrong skill to handle user input and may result in unintended creation workflows or collection of sensitive repository/configuration data.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest context for this file is pipeline creation, and the file description says it is used to create new pipelines/CI configuration. However, the API table explicitly includes `/rest/openapi/pipeline/runByManual` for executing pipelines, which is a separate execution-management capability rather than a necessary implementation detail of creation.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger list includes the broad term "编辑流水线" (edit pipeline), which can activate a detail-retrieval skill in situations that imply modification intent rather than read-only access. Because this endpoint returns the full pipeline configuration, overly broad invocation increases the chance of unnecessary exposure of sensitive build configuration, repository details, and stage definitions to users or downstream agents who only intended an edit workflow.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The skill description states that it fetches complete pipeline configuration but does not warn that the response may contain sensitive operational metadata such as repository URLs, branch settings, triggers, stages, and other internal pipeline parameters. In a DevOps context, exposing full configuration without clear disclosure or minimization can lead to oversharing of internal infrastructure details and increase the blast radius of prompt-triggered data access.

Static analysis

No suspicious patterns detected.