T05 · Unauthorized Access and Privilege Escalation
- Location
stock_alert_workflow.py:40- Finding
WhatsApp Recipient Access-Control Policy Is Not Enforced
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its stock-alert purpose, but its WhatsApp recipient restrictions are documented and then not enforced, so it needs review before installation.
Install only after reviewing and tightening the send path: do not rely on the bundled WhatsApp constraints until the code enforces them, pin or lock dependencies, use a dedicated WhatsApp account/session for alerts, and remove or explicitly configure the Feishu/Lark document workflow if you do not intend that extra data flow.
stock_alert_workflow.py:40WhatsApp Recipient Access-Control Policy Is Not Enforced
requirements.txt:1Unpinned Third-Party Dependencies Make Installation Non-Reproducible
The documented purpose does not align with the detected behavior set, including undeclared historical/financial data retrieval and local dataset loading while apparently lacking the stated alert delivery path. Description-behavior mismatches are dangerous because they can hide unexpected capabilities from users and reviewers, increasing the chance of unapproved data access or covert functionality.
The manifest declares install steps and documents shell/env-driven behavior, but it does not explicitly scope or declare the tools/permissions the skill needs. That weakens reviewability and policy enforcement, making it easier for a skill to execute shell commands or use environment-controlled behavior without clear operator approval.
The skill is designed to send WhatsApp messages on the user's behalf, but the documentation does not provide a prominent warning or explicit consent boundary before transmission. In messaging contexts, insufficient user notice can lead to accidental disclosure, spam-like behavior, or sending sensitive financial information to the wrong recipient or group.
The manifest's Permissions section says the skill 'optionally syncs reports to Feishu/Lark docs' and references Feishu permission handling, implying a second delivery capability beyond WhatsApp. However, the rest of the file describes only WhatsApp delivery via wu, and the listed implementation files contain no Feishu/Lark component, creating a semantic mismatch between claimed scope and actual functionality.
The skill metadata describes WhatsApp-only stock alert delivery, but this document adds an undisclosed Feishu/Lark publishing path. That expands the data-flow and permissions surface beyond the declared capability, creating a risk of unauthorized persistence or distribution of watchlists and alert content to another platform that operators may not expect or monitor.
These instructions establish bot write access, shared groups, and persistent report workflows in Feishu that are not disclosed in the skill description. Hidden or undocumented write-capable integrations are dangerous because they can be abused to exfiltrate alert content, create untracked records, or bypass the tighter WhatsApp recipient allowlist by copying data into a broader collaboration system.
The manifest describes a skill for generating stock price watchlist alerts delivered to WhatsApp, with live quotes and local CSV fallback. This file also implements historical price retrieval, company financial metrics lookup, and loading full S&P 500/NASDAQ datasets, which are broader analytics/data-access capabilities not implied by a simple alerting skill.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if shutil.which("wu") is None:
return "skipped", "wacli `wu` not installed (npm i -g @ibrahimwithi/wu-cli)"
try:
result = subprocess.run(
["wu", "send", recipient_jid, message],
capture_output=True, text=True, check=True,
)
This code performs a live network call via yfinance to fetch historical stock data, but there is no visible confirmation prompt, logging, or user-facing warning at the point of execution. The docstring notes that network access is required, but that is developer-facing code documentation rather than a clear user disclosure.
The function retrieves live company financial data through yfinance, which implies an outbound network request. While the docstring says the lookup is live, there is no visible user-facing notice, prompt, or logging indicating that external data will be requested.
The dependency yfinance is specified with a lower bound only, so installations can resolve to different future versions over time. This weakens build reproducibility and can unintentionally introduce a vulnerable or malicious upstream release into the skill's execution environment.
yfinance>=0.2.37
pandas>=2.2.0
pyyaml>=6.0.1
The pandas dependency is unpinned, which allows arbitrary newer versions to be installed depending on resolver behavior and install time. This creates supply-chain risk and makes it difficult to verify whether known vulnerable versions are excluded.
yfinance>=0.2.37
pandas>=2.2.0
pyyaml>=6.0.1
The manifest does not pin pandas, so it is impossible to determine from this file alone whether deployment will use a version affected by known advisories. While the cited advisory is disputed and may not apply, the lack of version certainty prevents reliable vulnerability assessment and increases package risk in production.
PyYAML is declared with only a minimum version, so the environment may install different releases over time, including versions later found to be vulnerable. Because PyYAML has a history of unsafe deserialization issues, leaving it unpinned increases uncertainty and supply-chain exposure.
yfinance>=0.2.37
pandas>=2.2.0
pyyaml>=6.0.1
PyYAML has multiple historical advisories related to unsafe parsing and deserialization, and the unpinned manifest makes it unclear whether a safe version will be installed. In a skill that may process configuration or watchlist data, an affected PyYAML version could increase the risk of code execution or parser abuse if untrusted YAML is ever consumed.
No suspicious patterns detected.