T09 · Insecure Skill Coding Practices
- Location
check_install.py:65- Finding
API Key Material Is Exposed in Terminal and Automation Logs
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This PPT skill is purpose-aligned overall, but it exposes part of a stored API key and makes live external API calls without enough user-facing control or disclosure.
Review this skill carefully before installing. It is not showing evidence of a backdoor or destructive behavior, but it can send your presentation content to Volces/Seedream, use your configured API key, consume paid API quota, and the install checker currently prints part of that key. Avoid using it with confidential or regulated material unless you accept that third-party processing, and remove the key-prefix logging before running the checker in any captured terminal or shared environment.
check_install.py:65API Key Material Is Exposed in Terminal and Automation Logs
baoyu_seedream_ppt.py:82Unvalidated API-Supplied Image URL Enables Server-Side Request Forgery and Resource Exhaustion
SKILL.md:25Installation Instructions Use Unpinned Third-Party Dependencies
The documented behavior goes beyond simple PPT generation by reading ~/.openclaw/config.json for API credentials, performing connectivity checks, and reportedly displaying part of the API key. Accessing secrets and making outbound validation requests are sensitive actions; if not clearly disclosed and scoped, they can expose credentials or surprise users with data egress.
The README explicitly promotes generating content through an external Seedream/Volces API and instructs users to configure an API key, but it does not warn that presentation content may be transmitted to a third-party service. In a PPT-generation workflow, users may submit internal business plans, product roadmaps, or personal data, so the missing privacy notice can lead to inadvertent data disclosure.
The skill instructs execution of Python scripts that read local files, write output artifacts, and make network requests, but it declares no explicit tool scope or permissions. This weakens sandboxing and user transparency, increasing the chance the skill can access local configuration and external services without clear consent boundaries.
The natural-language content of the skill consistently uses Chinese for the description, triggers, and operating instructions, but it does not state that the user can choose another language. This can amount to forcing a specific language/locale without user opt-in.
The trigger list includes a very generic phrase, "生成PPT", which could match many ordinary conversations about making presentations rather than intentional invocation of this specific skill. The description does not provide exclusions, context limits, or negative examples to narrow when the skill should activate.
This code performs external network transmission of prompt data to a remote API endpoint. External transmission is expected for an image-generation skill, but it remains security-relevant because the transmitted content may include sensitive user material and there are no trust-boundary warnings or consent controls in the workflow.
"size": resolution
}
response = requests.post(
f"{BASE_URL}/images/generations",
headers=headers,
json=data,
The tool sends user content and fully assembled prompts to a third-party image-generation API, but it provides no explicit disclosure or consent mechanism before transmitting potentially sensitive material off-host. In the context of a PPT generator that may process internal business content, this creates a real confidentiality and privacy risk through unintended remote sharing.
The manifest description explicitly says the skill supports an interactive staged confirmation process to reduce repeated edits and API usage. In this file, main() reads inputs, generates prompts, calls the image API for every page, downloads results, and builds the PPT without any interactive confirmation checkpoints or review loop.
The code forcibly replaces the language placeholder with "Chinese" for all generated prompts. This is a natural-language locale constraint with no opt-in, override flag, or explanation that the tool is intended only for a China-specific workflow.
The script prints the first 20 characters of the API key to the console, which is unnecessary secret disclosure. Console output may be captured by terminal logs, screenshots, CI logs, shell history wrappers, or remote support sessions, allowing partial credential leakage that can aid key identification or correlation.
The script automatically uses the user's stored API credential to make a live request to an external service as part of an install check. Although testing connectivity is a legitimate goal, transmitting credentials during installation verification without clear opt-in, dry-run mode, or prominent disclosure can surprise users and trigger unintended external account usage, logging, or billing.
This duplicate finding identifies the same outbound transmission behavior: the script sends a test image-generation request to an external endpoint with authorization headers. The risk is contextual rather than overtly malicious, but in a setup verifier it still creates privacy, billing, and transparency concerns.
"prompt": "test",
"size": "2560x1440"
}
response = requests.post(
"https://ark.cn-beijing.volces.com/api/v3/images/generations",
headers=headers,
json=data,
This duplicate finding identifies the same outbound transmission behavior: the script sends a test image-generation request to an external endpoint with authorization headers. The risk is contextual rather than overtly malicious, but in a setup verifier it still creates privacy, billing, and transparency concerns.
"prompt": "test",
"size": "2560x1440"
}
response = requests.post(
"https://ark.cn-beijing.volces.com/api/v3/images/generations",
headers=headers,
json=data,
This file is a code file, so SQP-3 applies to natural-language policy issues in code literals and behavior. The prompt template forcibly replaces {{LANGUAGE}} with "Chinese", which imposes a specific language/locale on all generated output without any user opt-in or documented region-specific justification.
The code comments imply user-modified prompts may be reused, but the implementation discards those edits and generates fresh prompts. In a skill designed around stepwise human confirmation to save quota and avoid repeated mistakes, this is a workflow-integrity flaw that can silently override reviewed content and send different data to the external model than the user approved.
The code comments imply user-modified prompts may be reused, but the implementation discards those edits and generates fresh prompts. In a skill designed around stepwise human confirmation to save quota and avoid repeated mistakes, this is a workflow-integrity flaw that can silently override reviewed content and send different data to the external model than the user approved.
A skill description that effectively forces a single language can violate language/locale policy when no opt-in or alternative is provided. This README presents all user-facing instructions exclusively in Chinese and does not mention language options or a justified region-specific scope.
The skill's stated purpose is generating image-based PPTs from content, layout, and style inputs. Reading credentials from ~/.openclaw/config.json reaches beyond the immediate document-processing task and introduces access to broader user-scoped configuration data that the manifest description does not mention.
The script's docstrings and all printed messages are in Chinese, with no user opt-in or explanation that the skill is intended only for Chinese-speaking users. This can violate a language/locale policy when a skill mandates a specific language by default.
The manifest description is written entirely in Chinese and describes the skill in a way that implies a fixed Chinese-language experience, without indicating any language choice or opt-in. This can be a natural-language policy concern when a skill appears to impose a specific language or locale without documenting flexibility or justification.
No suspicious patterns detected.