T09 · Insecure Skill Coding Practices
- Location
llm.py:51- Finding
Documented Custom LLM Endpoint Is Ignored, Potentially Disclosing Third-Party API Keys to OpenAI
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly a coherent fund-analysis assistant, but it misstates where LLM keys and portfolio data are sent and can transmit detailed holdings externally.
Review llm.py before use. Do not set a third-party LLM key expecting LLM_API_BASE to route it elsewhere, because this version sends LLM requests to OpenAI. Treat analysis as externally processed and assume exact holdings, transaction dates, prices, quantities, and notes may be included in prompts. Use a dedicated low-limit API key, avoid sensitive notes in positions.json, and only configure push/webhook URLs you control.
llm.py:51Documented Custom LLM Endpoint Is Ignored, Potentially Disclosing Third-Party API Keys to OpenAI
macro_fetcher.py:132Untrusted Tavily Search Results Are Inserted Directly into LLM Investment Prompts
ai_analysis.py:213Ordinary AI Analysis Transmits Detailed Portfolio and Transaction Information Without Granular Consent
positions.py:33Sensitive Portfolio Records Are Written with Process-Default Permissions and Non-Atomic Updates
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
headers={"Content-Type": "application/json"},
method="POST",
)
with urllib.request.urlopen(tv_req, timeout=10) as tv_response:
tv_data = json.loads(tv_response.read().decode("utf-8"))
answer = tv_data.get("answer", "")
m = re.search(r'7\.\d{3,4}', answer)
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
)
try:
with urllib.request.urlopen(req, timeout=90) as resp:
result = json.loads(resp.read().decode("utf-8"))
choices = result.get("choices", [])
if choices:
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
| Required | Description |
|----------|----------|-------------|
| LLM_MODEL | ✅ | Model name, e.g. gpt-4o-mini |
| LLM_API_KEY | ✅ | Corresponding API key |
| TAVILY_API_KEY | ❌ | Tavily API for real-time macro search |
| PUSH_WEBHOOK_URL | ❌ | Webhook push (WeCom / Feishu / Slack) |
| BARK_PUSH_URL | ❌ | iOS Bark notification |
| PUSH_EMAIL | ❌ | Email push |
# Macro event monitor (weekday morning)
openclaw cron add --cron "0 8 * * 1-5" \
--message "cd /path/to/fund-ai-assistant && python3 event_monitor.py --dry-run"
# Fund tracking analysis (weekday morning)
openclaw cron add --cron "30 9 * * 1-5" \
--message "cd /path/to/fund-ai-assistant && python3 analyzer.py analyze"
# Multi-agent debate (Friday morning)
openclaw cron add --cron "30 9 * * 5" \
--message "cd /path/to/fund-ai-assistant && python3 debate_analyzer.py 000001"
本项目的诞�
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
If the actual implementation is focused on single-fund analytics rather than portfolio-level management, the issue is again inaccurate disclosure. In this finance context that matters because users may infer broader safeguards or data-processing expectations than the tool actually has.
Referenced artifact was not completely inspected
| `analyzer.py` | Main entry, tracking + analysis | `python3 analyzer.py list` |
The skill documents capabilities that involve environment variables, local file access, file creation, and outbound network activity, but it does not declare any explicit tool scope or permissions. This weakens reviewability and consent because a user or host platform cannot easily tell what sensitive capabilities the skill expects before use.
The skill explicitly supports external transmission to LLM endpoints and other services, including use of a configurable API base. In a finance assistant, this is sensitive because fund data, prompts, and the API key may be sent off-host; a malicious or mistyped custom endpoint can exfiltrate credentials and investment data.
| Variable | Description |
|----------|-------------|
| `LLM_API_BASE` | ⚠️ Custom API URL — if untrusted, your key and data go there. Use endpoints you control. Default: `https://api.openai.com/v1` |
| `TAVILY_API_KEY` | Tavily API for real-time macro search |
| `FUND_SCENE_DIR` | Directory with optional `.md` scene templates (default: `./scenes/`) |
| `PUSH_WEBHOOK_URL` | Generic HTTP POST webhook (WeCom / Feishu / Slack) |
The recommended precautions confirm that the skill can send API keys and fund data to whatever LLM_API_BASE is configured. Even though the document warns about this, the capability remains a real security risk because the tool handles financial context and secret-bearing requests.
### Recommended Precautions
1. **Use a dedicated LLM API key** — not your main production key.
2. **⚠️ Inspect `LLM_API_BASE`** — if set to an untrusted endpoint, your API key and fund data will be sent there. Only use `https://api.openai.com/v1` or endpoints you control.
3. **Review `llm.py` and `fund_api.py`** before first run.
4. **Run in an isolated environment** (container or VM) on first use.
5. **Do not set `FUND_SCENE_DIR`** to sensitive directories.
The trigger list contains very generic terms such as "Fund," "portfolio," and "rebalance," which are likely to match ordinary financial conversations outside the skill's intended scope. Overly broad activation can cause the skill to engage unexpectedly and send user prompts or portfolio-related context to external services, increasing privacy and prompt-routing risk.
The module explicitly instructs the LLM to provide 'professional, clear, actionable investment advice' including buy/sell actions, position sizing, stop-loss, and take-profit levels, but it does not attach a user-facing financial-risk warning or suitability disclaimer. In a fund-trading context, this can cause users to over-trust model output as personalized financial advice, increasing the risk of harmful or inappropriate investment decisions.
The prompt is written entirely in Chinese and mandates a Chinese JSON schema and response behavior, which effectively fixes the skill's output language. Under the policy, forcing a specific language without user opt-in or a documented justification is a natural-language policy violation.
This Python file contains user-facing natural language in the module docstring and command help text entirely in Chinese, which forces a specific language for interaction. The policy allows locale constraints only when the tool offers user choice or clearly documents a justified region-specific limitation, neither of which is present here.
The manifest emphasizes tracking, AI analysis, macro monitoring, technical indicators, and rebalancing alerts. In addition to those analytics functions, this file implements buy/sell record creation and record deletion commands, which change persisted position data and move the skill beyond passive tracking/analysis into portfolio bookkeeping and trade-log maintenance.
No suspicious patterns detected.