T09 · Insecure Skill Coding Practices
- Location
scripts/translate_ppt.py:301- Finding
Unrestricted API Endpoint Can Expose Presentation Content and API Credentials
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill does what it says, but it can send presentation text, speaker notes, and API credentials to arbitrary LLM endpoints without strong safeguards.
Review this before installing. Use it only with a trusted local endpoint or a trusted HTTPS cloud provider, avoid putting API keys on the command line, and assume Chinese slide text plus speaker notes may be sent to the configured model service. Do not use it on confidential decks unless the endpoint and provider data-handling terms are acceptable.
scripts/translate_ppt.py:301Unrestricted API Endpoint Can Expose Presentation Content and API Credentials
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Determine output path
output_path = get_output_path(args.input_file, args.output_file)
# Get API key from args or environment
api_key = args.api_key or os.environ.get("LLM_API_KEY", "")
# Soft connectivity check (warning only)
The skill documentation indicates capabilities that can access environment data and make network requests, but it does not declare any explicit tool scope or allowed-tools boundary. This weakens least-privilege controls and can lead to unintended access to secrets or external services if the skill is executed in a permissive agent environment.
Several trigger phrases like 'translate slides' or 'presentation translation' are broad enough to activate this skill for requests outside the intended Chinese-PPTX-to-English workflow. Over-broad activation can cause the wrong skill to handle user data, increasing the chance of accidental file processing or transmission to an LLM endpoint without user intent.
The skill describes use of local or cloud OpenAI-compatible endpoints but does not clearly warn that slide text may be sent off-box for translation. Users may provide confidential presentations without realizing their contents could be transmitted to third-party or local model services, creating a meaningful privacy and data-handling risk.
The skill explicitly supports sending presentation text to an external cloud API endpoint, which constitutes external data transmission. In the context of business presentations, the content may include proprietary, financial, or personal information, so transmitting it to a third party without strong disclosure and consent can expose sensitive data.
Run with your cloud endpoint:
python .qoder/skills/translate-ppt/scripts/translate_ppt.py input.pptx --api-base https://api.openai.com/v1 --api-key sk-xxx --model gpt-4o
The skill is explicitly designed to extract slide text and send it to OpenAI-compatible APIs, including third-party cloud providers, but the reference does not describe any user-facing consent, privacy warning, or data handling constraints. Because presentation content often contains confidential business information, silently transmitting extracted text off-host creates a real confidentiality risk.
This code performs an outbound HTTP request containing extracted presentation text in the request payload, which is a genuine external data transmission path. In the context of PPT translation, this is functionally necessary, but it is still security-relevant because sensitive slide contents may be sent to an external service depending on api_base.
if api_key:
headers["Authorization"] = f"Bearer {api_key}"
response = requests.post(url, json=payload, headers=headers, timeout=120)
response.raise_for_status()
result = response.json()
translated_text = result["choices"][0]["message"]["content"]
The documented implementation again issues a POST request to an OpenAI-compatible endpoint with presentation text, confirming another direct exfiltration path for slide content. Even though it is expected behavior for translation, it remains a true security concern if users are not clearly informed or if the endpoint is untrusted.
if api_key:
headers["Authorization"] = f"Bearer {api_key}"
response = requests.post(url, json=payload, headers=headers, timeout=120)
response.raise_for_status()
result = response.json()
return result["choices"][0]["message"]["content"]
The documentation explicitly lists OpenAI's cloud API endpoint as a supported destination, which increases the likelihood that extracted presentation text will be sent to an external third party. This is not exploit code by itself, but in conjunction with the described request flow it represents a real data exposure risk.
|----------|--------------|----------------|
| Qoderwork | (provided by client) | As needed |
| Ollama | `http://localhost:11434/v1` | None required |
| OpenAI | `https://api.openai.com/v1` | API key required |
| DeepSeek | `https://api.deepseek.com/v1` | API key required |
| Other | Varies | Varies |
The documentation also lists DeepSeek's cloud API endpoint, reinforcing that third-party remote transmission of extracted slide text is a supported and likely deployment mode. For business presentations, this can expose proprietary or regulated information if users assume translation is performed locally.
| Qoderwork | (provided by client) | As needed |
| Ollama | `http://localhost:11434/v1` | None required |
| OpenAI | `https://api.openai.com/v1` | API key required |
| DeepSeek | `https://api.deepseek.com/v1` | API key required |
| Other | Varies | Varies |
### System Prompt
This retry path repeatedly transmits the same extracted text to the configured endpoint on failures, potentially increasing exposure of sensitive content and broadening the chance of interception or unintended retention by the service. The repeated outbound requests confirm that data leaves the environment and may do so multiple times.
for attempt in range(MAX_RETRIES): # MAX_RETRIES = 3
try:
response = requests.post(url, json=payload, headers=headers, timeout=120)
response.raise_for_status()
result = response.json()
return parse_numbered_response(result["choices"][0]["message"]["content"], len(segments))
Natural-language strings in the docstring and prompt specify a fixed translation direction from Chinese to English and instruct the model to return English only. The file does not offer a user opt-in or configurable target language, which is a language/locale policy concern under the stated rules.
The script extracts, translates, and rewrites slide notes in addition to visible slide content. Notes often contain speaker guidance, internal commentary, or sensitive material not implied by a user request to translate the presentation itself, so this expands data access and modification scope beyond the declared skill purpose.
The translation batch function sends extracted presentation text to an external LLM API but does not present an explicit privacy warning or obtain informed user consent. If slides contain confidential business, legal, or personal information, this can cause unauthorized disclosure to third-party services.
This network call transmits presentation text to a configured API endpoint for translation. In the context of office documents, the content may include trade secrets, financial data, or internal notes, so external transmission is security-relevant even if it is part of intended functionality.
for attempt in range(MAX_RETRIES):
try:
response = requests.post(url, json=payload, headers=headers, timeout=120)
response.raise_for_status()
result = response.json()
translated_text = result["choices"][0]["message"]["content"]
The tool allows arbitrary OpenAI-compatible API endpoints, including cloud services, so presentation text can be sent to any remote host the operator supplies. That capability exceeds a narrowly described local PPT translation workflow and increases the risk of unintended exfiltration of confidential presentation content.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
python translate_ppt.py input.pptx --api-base http://localhost:PORT/v1 --model model-name
# Use with cloud API
python translate_ppt.py input.pptx --api-base https://api.example.com/v1 --api-key your-key --model gpt-4o
"""
)
The code saves a new PowerPoint file containing translated content and formatting changes. Although it prints the output path at save time, the top-level usage/help text does not explicitly warn that running the tool creates or overwrites an output presentation, which is a file-write operation affecting user data.
No suspicious patterns detected.