Back to skill

Security audit

uctoo-api-skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real backend API connector, but it needs review because it can automatically perform authenticated create, edit, and delete actions while handling credentials and tokens with weak safeguards.

Install only if you intend the agent to contact the UCTOO backend and potentially change or delete backend records. Use a low-privilege test account, avoid production passwords in chat, verify the backend URL is trusted HTTPS, do not pass real bearer tokens on the command line, and require explicit confirmation before any write or delete request.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/api_client.js:6
Finding
Credentials and Bearer Tokens Can Be Sent to an Arbitrary or Plaintext Backend## Vulnerability Details **File Location**: `scripts/api_client.js:6-7, 51-52, 65` **Vulnerability Type**: Unrestricted backend override and insecure transport of authentication material **Risk Level**: High ### Vulnerable Code ```javascript constructor() { this.baseUrl = process.env.BACKEND_URL || 'https://javatoarktsapi.uctoo.com'; this.accessToken = null; } ``` ```javascript const isHttps = fullUrl.startsWith('https://'); const client = isHttps ? https : http; ``` ```javascript if (requireAuth && this.isAuthenticated()) { options.headers['Authorization'] = `Bearer ${this.accessToken}`; } ``` ### Technical Analysis The client accepts `BACKEND_URL` directly from the process environment without validating its scheme, hostname, port, or origin. It explicitly supports both HTTPS and plaintext HTTP. The `login()` method sends the supplied username and password to this configured backend, and authenticated API calls automatically attach the stored bearer token. Environment configuration is a legitimate deployment mechanism, but authentication material should not be forwarded to an unrestricted origin. Supporting plaintext HTTP also exposes credentials and tokens to interception and modification by network-adjacent attackers. This behavior exceeds minimum privilege because the declared Skill only needs access to the UCTOO backend, not arbitrary network destinations. ### Attack Path 1. An attacker influences the runtime environment, deployment configuration, wrapper script, or service definition. 2. The attacker sets `BACKEND_URL` to an attacker-controlled URL or a plaintext HTTP endpoint. 3. A user invokes `login(username, password)`. 4. The client sends the supplied credentials to the configured destination. 5. If the destination returns a response containing `data.access_token`, the client stores that value. 6. Subsequent authenticated calls automatically send the bearer token ...[truncated 524 chars]
Remediation
## Remediation Suggestions 1. Require `https:` for every non-development backend and reject plaintext HTTP before sending a request. 2. Validate the parsed URL against an explicit allowlist of approved UCTOO hostnames, ports, and schemes. 3. Reject URLs containing embedded credentials, fragments, or unexpected ports. 4. Bind stored tokens to the exact origin that issued them. Never forward a token after an origin change. 5. Separate development support for localhost from production behavior and require an explicit insecure-development flag. 6. Avoid following cross-origin redirects for requests containing credentials or authorization headers. 7. Add tests proving that HTTP, unapproved hosts, malformed URLs, and origin changes are rejected.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/test_api.py:5
Finding
API Test Sends Fixed Credentials to an Unrestricted Backend at Import Time## Vulnerability Details **File Location**: `scripts/test_api.py:5-21` **Vulnerability Type**: Import-time network side effect and unsafe credential destination **Risk Level**: High ### Vulnerable Code ```python BACKEND_URL = os.environ.get('BACKEND_URL', 'https://javatoarktsapi.uctoo.com') print("Testing UCTOO API Client") print("========================") print(f"Backend URL: {BACKEND_URL}") print() # Test 1: Login print("Test 1: Login with demo / 123456") print("-" * 50) login_url = f"{BACKEND_URL}/api/uctoo/auth/login" login_data = {"username": "demo", "password": "123456"} headers = {"Content-Type": "application/json"} try: response = requests.post(login_url, json=login_data, headers=headers, timeout=60) ``` ### Technical Analysis The test accepts an arbitrary `BACKEND_URL` and immediately performs a login request using fixed credentials. It does not require HTTPS or validate the destination against an approved host. In addition, the network operation occurs at module scope, so importing the file executes the request without an explicit function call. The fixed credentials may only be intended as demonstration credentials, but the script still transmits authentication information. Import-time execution also violates the principle of least surprise and can trigger network activity during test discovery, static tooling, or reuse as a module. ### Attack Path 1. An attacker or compromised automation environment controls `BACKEND_URL`. 2. A user runs the README-recommended test command, or a test runner imports `scripts.test_api`. 3. Module-level statements construct a login URL using the attacker-controlled value. 4. The script sends `demo` / `123456` to that destination. 5. The attacker records the credentials and any associated request metadata. 6. If the credentials are valid on another deployment, the attacker attempts to reuse them. ### Impact Assessment The immediate impact is ...[truncated 317 chars]
Remediation
## Remediation Suggestions 1. Move all executable behavior into a `main()` function protected by `if __name__ == "__main__":`. 2. Require an explicit opt-in flag before performing a live integration test. 3. Require HTTPS and validate the backend against an allowlist. 4. Obtain test credentials from a protected secret provider rather than embedding them. 5. Use a dedicated, low-privilege test account with short-lived credentials. 6. Clearly separate unit tests from live integration tests so test discovery cannot cause network requests.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/test_api.py:21
Finding
Authentication Response and Token Material Are Exposed in Test Logs## Vulnerability Details **File Location**: `scripts/test_api.py:21-31` **Vulnerability Type**: Sensitive authentication data exposure through logs **Risk Level**: High ### Vulnerable Code ```python response = requests.post(login_url, json=login_data, headers=headers, timeout=60) print(f"Status Code: {response.status_code}") print(f"Response: {response.text}") if response.status_code == 200: result = response.json() if result.get('code') == 200 and 'data' in result: access_token = result['data'].get('access_token') if access_token: print(f"\n✅ Login successful! Access token obtained.") print(f"Token: {access_token[:50]}...") ``` ### Technical Analysis The script prints the complete body of the login response. According to the documented response format, that body can contain an `access_token` and associated user information. Consequently, the full token can be exposed before the later partial-redaction print is reached. Printing the first 50 characters of the token is also unsafe. Even when a prefix is not independently usable, it discloses authentication material and creates an avoidable correlation identifier in logs. Terminal output is frequently retained by CI systems, agent transcripts, shell capture tools, support bundles, and centralized logging services. ### Attack Path 1. A user or CI job runs the API test successfully. 2. The authentication endpoint returns an access token in the response body. 3. The script writes the complete response to standard output. 4. CI, terminal capture, an agent runtime, or centralized logging retains that output. 5. An attacker with log access extracts the bearer token. 6. Before expiration or revocation, the attacker sends authenticated requests using the stolen token. ### Impact Assessment A log reader may assume the complete privileges of the authenticated account for the token's lifetime. Depending on bac ...[truncated 215 chars]
Remediation
## Remediation Suggestions 1. Never print raw authentication response bodies. 2. Log only the HTTP status, a stable request identifier, and a generic success or failure message. 3. Remove the token-prefix print entirely. 4. Introduce centralized redaction for fields such as `access_token`, `refresh_token`, `Authorization`, `password`, and cookies. 5. Configure CI and agent runtimes to mask known secret patterns and restrict log access and retention. 6. Revoke any tokens that may already have appeared in retained logs.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/api_client.py:56
Finding
Bearer Tokens Are Accepted and Documented as Command-Line Arguments## Vulnerability Details **File Location**: `scripts/api_client.py:56-67` **Vulnerability Type**: Sensitive token exposure through process arguments and shell history **Risk Level**: Medium ### Vulnerable Code ```python def main(): """ Command-line entry point Usage: python api_client.py <method> <endpoint> [data_json] [token] """ if len(sys.argv) < 3: print(json.dumps({"error": "Usage: python api_client.py <method> <endpoint> [data_json] [token]"})) sys.exit(1) method = sys.argv[1] endpoint = sys.argv[2] data = json.loads(sys.argv[3]) if len(sys.argv) > 3 else None token = sys.argv[4] if len(sys.argv) > 4 else None result = make_request(method, endpoint, data, token) ``` The same unsafe interface is explicitly recommended in `REFACTORING_PLAN_v2.md:216-219`: ```bash python scripts/api_client.py GET "/api/uctoo/user/10/0" "" "your_token_here" ``` ### Technical Analysis Command-line arguments are not an appropriate secret transport mechanism. Depending on the operating system and runtime environment, arguments may be visible through process inspection, audit telemetry, shell history, job metadata, crash reports, command logging, and agent execution transcripts. The script's documented interface encourages users or agents to substitute a real bearer token directly into the command. The token is then copied into process memory and an `Authorization` header. ### Attack Path 1. A user or agent follows the documented command format and places a real token in the fourth argument. 2. The command is recorded in shell history, an agent transcript, CI job metadata, or process-monitoring telemetry. 3. A local user, administrator, log reader, or compromised monitoring component retrieves the argument. 4. The attacker extracts the bearer token. 5. The attacker replays it against authenticated UCTOO API endpoints b ...[truncated 383 chars]
Remediation
## Remediation Suggestions 1. Remove the token positional argument from the command-line interface. 2. Read tokens from a protected secret manager, operating-system credential store, or inherited file descriptor. 3. If standard input is used, ensure the token is not echoed or included in diagnostic output. 4. Prefer short-lived tokens with narrowly scoped backend permissions. 5. Update `REFACTORING_PLAN_v2.md` and all examples so no command contains a token. 6. Document token revocation and rotation procedures for accidental exposure.

T09 · Insecure Skill Coding Practices

Warning
Location
README_zh_CN.md:315
Finding
Documentation Recommends Hardcoding a Provider API Key in Source Code## Vulnerability Details **File Location**: `README_zh_CN.md:315-321` **Vulnerability Type**: Insecure API-key storage guidance **Risk Level**: Medium ### Vulnerable Documentation ```markdown 1. Deploy https://gitee.com/UCT/uctoo-backend 2. **Configure API key**: In the `main.cj` file of the `uctoo_api_mcp_client` project, replace `<your api key>` with your DeepSeek API key. ```cangjie Config.env["DEEPSEEK_API_KEY"] = "sk-xxxxxxxxxx"; ``` ``` ### Technical Analysis The setup procedure instructs users to place a DeepSeek API key directly in a source file. Source code is commonly committed to version control, copied into build contexts, included in artifacts, backed up, shared for support, or exposed through code-review systems. Although the displayed value is a placeholder rather than a live secret, the recommended workflow causes users to replace it with a real credential. This creates a persistent secret-management weakness. ### Attack Path 1. A developer follows the documented setup procedure. 2. The developer replaces the placeholder with a real provider API key. 3. The modified file is committed, uploaded, packaged, backed up, or shared. 4. An attacker or unauthorized collaborator retrieves the source or artifact. 5. The attacker extracts the key and makes provider API calls under the victim's account. ### Impact Assessment Exposure can permit unauthorized use of the associated AI provider account, resulting in consumption charges, quota exhaustion, service disruption, or access to provider resources available to that key. This does not inherently provide host-level privileges.
Remediation
## Remediation Suggestions 1. Replace the source-code assignment with runtime retrieval from a secret manager or environment variable. 2. Provide a sanitized `.env.example` containing only variable names, never values. 3. Ensure `.env` and local secret files are excluded from version control. 4. Add pre-commit and CI secret scanning. 5. Use provider keys with minimum required permissions, quotas, and expiration where supported. 6. Rotate any real keys previously stored in source history and remove them from repository history.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/api_client.py:39
Finding
Python API Client Omits Network Timeouts## Vulnerability Details **File Location**: `scripts/api_client.py:39-43` **Vulnerability Type**: Unbounded network wait and resource exhaustion **Risk Level**: Low ### Vulnerable Code ```python try: if method.upper() == "GET": response = requests.get(url, headers=headers, params=data) elif method.upper() == "POST": response = requests.post(url, headers=headers, json=data) else: return json.dumps({"error": f"Unsupported method: {method}"}) ``` ### Technical Analysis Neither request specifies a connection or response timeout. The `requests` library can therefore wait indefinitely if the remote endpoint accepts a connection but does not complete the response. In an agent or automation environment, repeated stalled invocations can consume workers, file descriptors, connections, and execution capacity. ### Attack Path 1. The backend becomes unavailable, is misconfigured, or intentionally accepts connections without responding. 2. The agent invokes the Python API client. 3. The request remains blocked without a deadline. 4. Additional requests create more blocked workers or processes. 5. Available execution capacity is exhausted or the user workflow remains indefinitely unavailable. ### Impact Assessment This primarily affects availability. It does not directly expose credentials or grant additional privileges, but it can stall Skill execution and contribute to denial of service in constrained agent runtimes.
Remediation
## Remediation Suggestions 1. Set explicit connect and read timeouts, for example `timeout=(5, 30)`. 2. Enforce an overall operation deadline at the agent or subprocess layer. 3. Use bounded retries only for transient failures, with exponential backoff and jitter. 4. Return structured timeout errors without exposing credentials or complete request data. 5. Add tests for connection timeout, response timeout, and retry exhaustion.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (41)

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

Critical
Category
Data Flow
Content
headers = {"Content-Type": "application/json"}

try:
    response = requests.post(login_url, json=login_data, headers=headers, timeout=60)
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.text}")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
L407-L411 将 `UctooAPISkill` 描述为负责“请求执行”,而 L465-L467 又明确说该项目“不直接发起HTTP请求”,实际网络调用由 `uctoo_api_mcp_server` 完成。两处文档对技能执行边界给出互相排斥的说法,容易误导审计者和调用方对技能能力的判断。

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill advertises destructive operations such as deleting users, products, and orders, but the design does not require confirmation, preview, or role/permission checks at the skill layer. For a backend integration skill, accidental or socially engineered deletion requests could directly cause irreversible business data loss.

Missing User Warnings

High
Confidence
99% confidence
Finding
The documentation instructs users to provide usernames and passwords directly in chat, but provides no safeguards for credential handling, redaction, retention, or safer authentication alternatives. This creates a significant risk of credential exposure in logs, transcripts, model context, or downstream tooling.

Missing User Warnings

High
Confidence
98% confidence
Finding
The design passes usernames, passwords, and bearer tokens directly via command-line arguments and then transmits them to a remote backend, but provides no explicit warning about process-list exposure, shell history leakage, or handling of sensitive data. In many environments, command-line arguments are visible to other local users or captured in logs, making credential theft realistic and severe.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior claims broad backend integration and natural-language-driven API execution, but the analyzed content does not substantiate that breadth. This mismatch is dangerous because reviewers or users may over-trust the skill's coverage and safeguards, leading to unsafe assumptions about what requests will be made and how inputs are handled.

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill instructs the agent to directly issue real API calls, including add/edit/delete operations, without prominent user-facing warnings or confirmation requirements. In this context, that is particularly risky because the backend appears capable of authenticated state-changing operations, so a casual request could modify or delete live data.

Credential Access

High
Category
Privilege Escalation
Content
if result.get('code') == 200 and 'data' in result:
            access_token = result['data'].get('access_token')
            if access_token:
                print(f"\n✅ Login successful! Access token obtained.")
                print(f"Token: {access_token[:50]}...")
            else:
                print("\n⚠️  Login response but no access token found")
Confidence
97% confidence
Finding
The script retrieves an access token from the login response and then handles it in a way that leads to exposure in logs. Even partial token disclosure is sensitive because logs are often broadly accessible, retained, and aggregated, increasing the chance of credential misuse or aiding token reconstruction/targeting.

Credential Access

High
Category
Privilege Escalation
Content
print(f"\n✅ Login successful! Access token obtained.")
                print(f"Token: {access_token[:50]}...")
            else:
                print("\n⚠️  Login response but no access token found")
        else:
            print(f"\n⚠️  Login failed: {result.get('message', 'Unknown error')}")
    else:
Confidence
99% confidence
Finding
This line explicitly prints the first 50 characters of the access token, which is direct secret leakage. In CI logs, terminals, or shared support artifacts, that disclosure can expose bearer credentials or enough token material to facilitate account compromise depending on token format and backend validation.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The skill advertises activation on broad everyday keywords such as “登录”, “产品”, “订单”, and “认证”, which can overlap with ordinary conversation and cause unintended invocation of a capability that issues real HTTP API requests. In this skill context, accidental activation is more dangerous because the described behavior is to directly translate natural language into backend operations, including authentication and CRUD actions against a live system.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
文档前部在“API集成”部分直接宣称该技能与 uctoo-backend 无缝集成并支持标准 CRUD 操作,整体表述为技能自身执行 API 调用。但在后文又明确说明 `uctoo_api_skill` 不直接发起 HTTP 请求,实际请求由 `uctoo_api_mcp_server` 发起(L465-L467)。这不是简单遗漏,而是对技能实际行为边界的主动性矛盾描述。

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
文档早前宣称“支持标准CRUD操作”,这通常意味着使用常见 REST 语义如 GET/POST/PUT/DELETE;但后文又明确说明系统“严格按照规范仅使用 GET 和 POST 方法,不使用 PUT、DELETE 等其他方法”(L352-L355)。这是对实现方式的实质性冲突,而非细节省略。

Missing User Warnings

Medium
Confidence
89% confidence
Finding
README 展示了使用真实用户名/密码登录、自动保存 token、后续自动注入 Authorization Header 的行为,但未明确警示这些凭据会被发送到后端并在会话中保留。结合该技能面向自然语言驱动的 API 调用场景,用户可能在不充分知情下输入敏感凭据,增加凭据泄露、越权调用和误操作风险。

Missing User Warnings

Medium
Confidence
93% confidence
Finding
README 明确说明“所有日志现在写入文件”且包含“完整的调试信息”,同时上下文中又涉及登录响应、access_token 提取和认证流程。若未声明脱敏与日志限制,极易将令牌、用户名、请求头或后端响应持久化到日志文件,导致本地或集中式日志系统中的敏感信息泄露。

Vague Triggers

Medium
Confidence
94% confidence
Finding
The proposed SKILL.md description explicitly triggers on broad natural-language keywords such as '产品', '订单', and '登录', which are common terms that may appear in ordinary conversation. In a skill that performs real backend HTTP requests, broad activation increases the chance of unintended invocation and accidental transmission or modification of backend data.

Vague Triggers

Medium
Confidence
97% confidence
Finding
The instruction '直接向我描述你想做什么,我会自动调用相应的API' encourages automatic execution from ambiguous natural-language input without an explicit approval boundary. In the context of a skill designed to issue live API requests, this can cause unintended state-changing requests or data disclosure when the user's wording is incomplete or misunderstood.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The execution flow states that the skill will parse user intent and execute API calls, but it does not warn that user-provided content may be sent to an external backend. In an API connector skill, missing disclosure increases the risk that users unknowingly submit sensitive personal or business data to the service.

Skill Enumeration

Medium
Category
Agent Snooping
Content
### A. 参考资料
- [Claude官方技能创建指南](../../../agentskills/docs/The-Complete-Guide-to-Building-Skill-for-Claude.md)
- [skill-creator 官方示例](../../skills/skill-creator/SKILL.md)
- [uctoo API设计规范](../../../../backend/docs/uctooAPI设计规范.md)
- [门控系统设计文档](../../../specs/004-agent-skill-runtime/skill_execution_design.md)
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger description uses very broad keywords such as '产品', '订单', '登录', and '认证', which increases the chance the skill activates on ordinary conversation or unrelated business requests. In an API-integration skill that is designed to translate natural language into live HTTP calls, accidental activation can lead to unintended authenticated requests or disclosure of backend data.

External Transmission

Medium
Category
Data Exfiltration
Content
if method.upper() == "GET":
            response = requests.get(url, headers=headers, params=data)
        elif method.upper() == "POST":
            response = requests.post(url, headers=headers, json=data)
        else:
            return json.dumps({"error": f"Unsupported method: {method}"})
Confidence
86% confidence
Finding
The code performs outbound HTTP requests to an external backend based on natural-language-driven API selection, which creates a real data exfiltration and unintended-action surface. In this skill context, external transmission is expected functionality, but it is still security-relevant because it may send sensitive business data, credentials, or tokens off-platform without strong guardrails.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The documentation includes delete operations as standard examples without warning that they may be irreversible or require heightened confirmation. In a skill intended to convert natural language into direct backend API calls, this omission increases the risk of accidental destructive actions from ambiguous user requests.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
L238 将该部分描述为“极简实现(仅提供 HTTP 工具)”,给人的含义是这里至少实现了一个可用的 HTTP 调用层;但 L279-L281 的注释和返回值明确表示实际 API 调用并不在该代码中完成,这里只是占位符。该注释/文档组合会误导读者对代码真实能力的判断,构成意图与代码的直接背离。

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
清单描述和文档大篇幅说明该技能支持用户管理、产品管理、订单管理、登录认证,并应直接发起实际 API 请求;但这里的实际 Skill 实现只读取 query/request 参数、记录日志并返回占位提示,没有进行任何 HTTP 请求或后端交互。该文件因此呈现出技能宣称能力与实际代码行为之间的明显不一致。

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill effectively instructs the agent to perform live network actions via `http_request`, including authenticated requests, but the manifest does not clearly declare a restrictive tool scope. That gap weakens reviewability and policy enforcement because operators and users cannot reliably tell what external capabilities the skill is expected to use.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger terms are very broad, including generic concepts like user management, products, orders, login, and authentication, which can cause the skill to activate in unrelated contexts. Because the skill directs real HTTP requests to a production backend, accidental activation could lead to unintended disclosure, state changes, or destructive operations.

Static analysis

No suspicious patterns detected.