T09 · Insecure Skill Coding Practices
- Location
scripts/create_rtq_deal.py:339- Finding
RTQ Access Key Exposed in Console and Agent Logs
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill matches its RTQ ad-order purpose, but it needs Review because it handles live credentials unsafely and can execute loosely discovered local helper scripts.
Install only after reviewing the credential risk. Do not paste production keys into chat; use a scoped test key or an out-of-band secret mechanism, verify the exact auth/logger dependencies before installation, and remove or rotate any RTQ keys that may have been printed or stored in ~/workspace/.order_cache.
scripts/create_rtq_deal.py:339RTQ Access Key Exposed in Console and Agent Logs
scripts/create_rtq_deal.py:117RTQ Access Key Persisted in Insecure Order Cache Files
scripts/create_rtq_deal.py:283Authentication Tool Can Be Spoofed Through Untrusted Dynamic Discovery
SKILL.md:124Executable Skill Dependencies Installed Without Version or Integrity Pinning
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.
The finding indicates the skill may primarily initialize configuration and persist credentials rather than perform the declared order-management functions. Undeclared secret collection and persistence are particularly risky because they expand the threat surface beyond the stated business function and can lead to credential leakage or misuse.
The finding indicates the skill may primarily initialize configuration and persist credentials rather than perform the declared order-management functions. Undeclared secret collection and persistence are particularly risky because they expand the threat surface beyond the stated business function and can lead to credential leakage or misuse.
The finding indicates the skill may primarily initialize configuration and persist credentials rather than perform the declared order-management functions. Undeclared secret collection and persistence are particularly risky because they expand the threat surface beyond the stated business function and can lead to credential leakage or misuse.
The finding indicates the skill may primarily initialize configuration and persist credentials rather than perform the declared order-management functions. Undeclared secret collection and persistence are particularly risky because they expand the threat surface beyond the stated business function and can lead to credential leakage or misuse.
The skill instructs users to paste full AK/SK and RTQ credentials directly into the conversation, but does not provide strong warnings about exposure in chat transcripts or safer input channels. Collecting long-lived secrets in plain conversational context is dangerous because they may be logged, retained, surfaced to other tools, or exposed through host compromise.
The skill explicitly directs users to provide secret API credentials in plaintext conversation and says those credentials will be saved locally. This creates a direct secret-handling vulnerability: sensitive credentials can be exposed through chat logs, local file compromise, backup systems, or insufficient filesystem protections, enabling unauthorized API access and business impact.
On successful order creation, the script stores rtqCluster and rtqAccessKey in a local JSON cache file. Persisting live access credentials in plaintext outside a dedicated secret store creates a direct secret exposure risk: any local user, malware, backup system, or later process that can read the file can reuse the credentials to access or manipulate RTQ resources.
Sensitive RTQ credentials are written to local storage with no warning, consent, encryption, or permission hardening. This is dangerous because users may be unaware that long-lived secrets are being persisted, increasing the likelihood of accidental leakage through shared machines, logs, backups, or support bundles.
The script scans local skill directories, heuristically selects any script containing identifying text, and then executes it via Python. An attacker who can place or modify a matching file in those searched directories can hijack execution and run arbitrary code in the agent context, potentially stealing credentials or altering RTQ operations.
The skill advertises shell, file read/write, and environment-dependent behavior but does not declare any explicit tool scope or permission boundaries. That creates unnecessary ambiguity about what resources the skill may access and increases the chance that the runtime grants broader capabilities than users expect, especially given the documented installation commands and local credential storage.
The create-request trigger words are broad enough that ordinary conversation mentioning '投放', '订单', or 'RTQ' could be misclassified as an action request. In a skill capable of credential checks, dependency installation, and API-side order changes, weak intent detection can cause unintended state-changing workflows to start.
Keyword-only request recognition without boundary constraints or negative cases is brittle and can route users into the wrong workflow. Given that the skill can prompt for secrets, inspect local state, and potentially install dependencies, accidental activation materially increases the risk of over-collection and unintended operations.
The skill includes automatic installation flows for auxiliary skills, which extends its effective capabilities beyond RTQ order management. Installing additional components via shell commands increases supply-chain and privilege risk, especially when the user may not understand that approving one skill causes execution and trust expansion to another.
The workflow adds local task-history recording that is not necessary to create or modify ad orders and may capture sensitive business and targeting information. Expanding into local recordkeeping without strong minimization and disclosure increases the blast radius of any compromise or accidental exposure of the host filesystem.
The task-recording flow encourages saving full order parameters and operational history to a local JSON file, likely including targeting attributes, audience identifiers, and other commercially sensitive data. Even if not always personal data, this unnecessary persistence creates confidentiality and compliance risk if the host or logs are accessed by other users, tools, or malware.
The module description and all user-facing strings are written exclusively in Chinese, indicating an implicit fixed locale for the skill experience. There is no natural-language indication that users may choose another language or opt in to Chinese, which can violate language/locale policy requirements.
The manifest describes RTQ order creation/query/update with a standardized interaction flow, but does not state that this skill will directly inspect host environment variables or scan local credential files in the current directory and home directory. Accessing local secrets is a broader host-access capability than the advertised business function itself and relies on undeclared local credential discovery behavior.
The cache helper writes order data to a persistent local file under the user's home workspace without any access-control hardening or sensitivity filtering. In context, this becomes a security issue because order details may include audience targeting metadata and, elsewhere in the script, the same cache mechanism is later used to store RTQ credentials.
The script executes another local Python script discovered from the filesystem via subprocess, creating a trust boundary issue: if the resolved auth_skill_path points to a tampered or malicious file, this code will run it with inherited privileges and sensitive request data. Although arguments are passed as a list rather than through a shell, the danger is arbitrary code execution through unsafe dependency/script discovery, not shell injection.
# 调用人群任务状态查询接口
request_body = {"audienceId": audience_ids[0], "pageNum": 1, "pageSize": 10}
result = subprocess.run(
["python3", auth_skill_path, "POST", "/audience/manage/taskList",
json.dumps(request_body, ensure_ascii=False)],
capture_output=True,
The script scans multiple local directories, inspects other skills' files, and selects a candidate script based on loose content matching before executing it. This broad filesystem discovery exceeds the stated function and materially increases the risk of executing a malicious planted script or interacting with unrelated files in a multi-skill environment.
This subprocess invocation sends RTQ credentials and order parameters to an external script selected earlier via dynamic path discovery. If that script is replaced or a malicious lookalike is found first, the call can exfiltrate credentials or execute arbitrary code, making this more severe because sensitive secrets are included in the payload.
# 调用鉴权技能的API模块
try:
result = subprocess.run(
["python3", auth_skill_path, "POST", "/rtq/deal/create",
json.dumps(params, ensure_ascii=False)],
capture_output=True,
The skill reads RTQ credentials from multiple local files and environment variables, and also persists order data locally under ~/workspace/.order_cache. This broad local data access and persistence exceeds the narrow action of modifying an RTQ order and creates unnecessary exposure of sensitive operational data on disk.
When cache is missing, final_params is built with rtqCluster and rtqAccessKey included, and on successful modification the entire structure is written to the local cache file. This stores live access credentials in plaintext without explicit disclosure, increasing the risk of credential theft from the workspace or subsequent processes/users.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if api_params['flowType'] == 'pc' and 'cookieType' in final_params:
api_params['cookieType'] = final_params['cookieType']
result = subprocess.run(
['python3', auth_skill_path, 'POST', '/rtq/deal/modify',
json.dumps(api_params, ensure_ascii=False)],
capture_output=True,
Detected: suspicious.exposed_secret_literal