T08 · Insecure Dependencies
- Location
scripts/generate_report.py:16- Finding
Automatic Installation of Unpinned Python Dependencies at Runtime
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly generates finance reports, but it also directs use of local Feishu credentials, external file transfer, runtime package installation, and unsafe document conversion settings.
Review before installing. Use this only in an isolated environment with pinned dependencies, avoid processing untrusted spreadsheets, prefer local HTML output, and require explicit approval before any Feishu credential use, file download, report upload, or message send.
scripts/generate_report.py:16Automatic Installation of Unpinned Python Dependencies at Runtime
scripts/generate_report.py:470Unescaped Input Rendered with Weakened Browser and Local-File Security Controls
The core purpose mostly aligns: the script performs financial analysis and creates rich reports with sparkline-like trend charts, and it supports HTML/PDF/DOCX/Markdown outputs. However, the declared description overstates supported inputs and triggers. The actual code only accepts a local Excel file path and parses .xlsx with openpyxl; there is no code for reading PDF files, CSV files, stock ticker lookup, or Feishu links/docs. Thus the description is not fully accurate and includes materially undeclared input capabilities that are absent from the code.
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
# Get token
TOKEN=$(curl -s -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d '{"app_id":"APP_ID","app_secret":"APP_SECRET"}' | python3 -c "import json,sys; print(json.load(sys.stdin)['tenant_access_token'])")
# Get file_key from message
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
-H 'Content-Type: application/json' \
-d '{"app_id":"APP_ID","app_secret":"APP_SECRET"}' | python3 -c "import json,sys; print(json.load(sys.stdin)['tenant_access_token'])")
# Get file_key from message
curl -s "https://open.feishu.cn/open-apis/im/v1/messages/{message_id}" -H "Authorization: Bearer $TOKEN"
# Download
curl -s "https://open.feishu.cn/open-apis/im/v1/messages/{message_id}/resources/{file_key}?type=file" \
-H "Authorization: Bearer $TOKEN" -o /tmp/data.xlsx
Directing the agent to retrieve app credentials from local configuration and use them to access and transmit files establishes a powerful secret-to-network path. In this context, the skill processes uploaded financial data, so the combination materially increases the risk of unauthorized access and exfiltration.
The script installs Python packages at runtime using os.system("pip install ..."), which executes a shell command and mutates the environment during normal operation. This creates supply-chain and environment integrity risk, and in this skill context it is more dangerous because the agent processes untrusted user files and should not also be fetching and executing code from package registries at runtime.
try:
import openpyxl
except ImportError:
os.system("pip install openpyxl -q")
import openpyxl
The Markdown fallback path installs markdownify at runtime via os.system("pip install ..."), again executing a shell command and downloading code dynamically. This is dangerous because a report-generation utility should not alter the host or trust live package retrieval when processing user-supplied documents.
except (FileNotFoundError, subprocess.CalledProcessError):
pass
try:
os.system("pip install markdownify -q")
from markdownify import markdownify
with open(html_path) as f:
md = markdownify(f.read(), heading_style="ATX")
The README advertises optional online benchmarking/search but does not disclose what data may be transmitted externally, which is important because users may upload sensitive financial statements or company data. In a finance-analysis skill, undisclosed network use can lead to unintended data exposure to third-party services or logs, especially when users expect local document processing.
The skill uses shell commands and writes files but declares no explicit tool scope or permissions boundaries. That increases the blast radius because an agent may invoke broader capabilities than users expect, especially in a workflow that handles local files and external APIs.
The skill instructs the agent to read Feishu app credentials from local configuration and use them for direct API access. That is dangerous because it normalizes secret retrieval from local files and enables authenticated access to external systems without clear user consent or platform mediation.
The workflow accesses credentials and transmits user files to Feishu APIs without any user-facing warning about secret use or external data transfer. This undermines informed consent and may expose confidential financial documents to third-party services unexpectedly.
This command initiates authenticated external communication to Feishu to obtain an access token. External transmission is not always malicious, but here it is risky because it is paired with local secret use and can enable broader outbound data access.
# Get token
TOKEN=$(curl -s -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d '{"app_id":"APP_ID","app_secret":"APP_SECRET"}' | python3 -c "import json,sys; print(json.load(sys.stdin)['tenant_access_token'])")
# Get file_key from message
The skill includes direct Feishu upload and message-sending steps that are not essential to the core report-generation logic. Embedding outbound file-delivery instructions creates an unnecessary data exfiltration channel for generated reports and any sensitive financial content they contain.
The skill tells the agent to upload generated reports to Feishu and send them as file messages, but does not warn that report contents leave the local environment. In a finance-analysis context, these files may include highly sensitive corporate or personal financial information.
The workflow explicitly creates a path for uploaded financial content to be repackaged into reports and transmitted through Feishu APIs. Because the skill's domain is financial analysis, the transmitted data is likely to be sensitive, making this more dangerous than generic file sharing guidance.
This command sends a file message through the Feishu API, creating a direct outbound channel for generated reports. In a financial-report skill, this can expose confidential financial analysis or source-derived content to external recipients if triggered without clear authorization.
FILE_KEY=$(echo "$UPLOAD" | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['file_key'])")
# 2. Send file message to chat
curl -s -X POST 'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id' \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"receive_id\":\"CHAT_ID\",\"msg_type\":\"file\",\"content\":\"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"}"
Runtime package installation is not necessary for the declared purpose of financial report generation and introduces environment-modifying behavior plus remote code supply-chain exposure. In an agent skill that handles user-provided files, this unnecessary capability broadens the attack surface significantly.
The HTML output explicitly sets lang="zh-CN", and the surrounding generated report content is also fixed in Chinese throughout the file. This forces a specific language/locale without any opt-in or configuration mechanism, matching the language/locale policy violation criteria.
The wkhtmltopdf conversion executes an external renderer on generated HTML derived in part from workbook content and explicitly enables local file access. In this context, untrusted spreadsheet text can flow into HTML without escaping, making the renderer step more dangerous because it may process attacker-controlled markup with access to local files.
["wkhtmltopdf", "--quiet", "--enable-local-file-access", "--page-size", "A4", "--orientation", "Landscape", html_path, pdf_path],
]:
try:
subprocess.run(cmd, check=True, capture_output=True)
return True
except (FileNotFoundError, subprocess.CalledProcessError):
pass
Launching a headless browser with --no-sandbox to render attacker-influenced HTML materially weakens isolation. Because the HTML report includes unescaped content from input spreadsheets and company/ticker fields, this conversion step increases the risk that malicious HTML/JS or browser parsing bugs could impact the host.
pass
for browser in ["chromium-browser", "chromium", "google-chrome"]:
try:
subprocess.run([browser, "--headless", "--disable-gpu", "--no-sandbox", f"--print-to-pdf={pdf_path}", html_path], check=True, capture_output=True)
return True
except (FileNotFoundError, subprocess.CalledProcessError):
continue
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def html_to_docx(html_path, docx_path):
try:
subprocess.run(["pandoc", html_path, "-o", docx_path, "--from=html"], check=True, capture_output=True)
return True
except (FileNotFoundError, subprocess.CalledProcessError):
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def html_to_markdown(html_path, md_path):
try:
subprocess.run(["pandoc", html_path, "-o", md_path, "--from=html", "--to=gfm"], check=True, capture_output=True)
return True
except (FileNotFoundError, subprocess.CalledProcessError):
pass
The Markdown conversion fallback changes the host environment by installing a package on demand, which is unrelated to safe document transformation at runtime. This unnecessarily grants the script a code-fetching and execution path from an external repository.
Nearly all user-facing documentation is presented only in Chinese, while the file does not state that the skill is intended exclusively for a Chinese-speaking or region-specific audience. Under the language/locale policy, forcing a specific language without user opt-in or justification is a natural-language policy concern.
This markdown reference uses substantial Chinese-language content alongside English headings and labels, which can impose a language/locale constraint on users without explicit opt-in. Under the policy rule, forcing a specific language is a natural-language policy concern unless the file offers a choice or clearly justifies the locale scope.
The script runs wkhtmltopdf, Chromium/Chrome, and pandoc as child processes, which is a safety-relevant operation for code files. Although conversion is part of the skill's purpose, there is no visible pre-execution disclosure in code comments, docstrings, or user-facing output that local external programs will be executed.
No suspicious patterns detected.