T09 · Insecure Skill Coding Practices
- Location
scripts/trading212_skill.py:30- Finding
Shared Parent Environment File Can Redirect Operations to Live Trading
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Trading212 skill is mostly coherent with its stated purpose, but it can submit real-money trades and uses broad external configuration/storage paths without strong runtime safeguards.
Install only if you are comfortable giving this skill access to your Trading212 account data and potential trading authority. Keep TRADING212_DEMO=true unless you intend real-money trading, use restricted/read-only credentials where possible, avoid storing secrets in shared parent .env files, and review or relocate the snapshot and rules paths before use.
scripts/trading212_skill.py:30Shared Parent Environment File Can Redirect Operations to Live Trading
scripts/proposal_rules.py:24Proposal Rules Are Loaded from an Unsafe External Default Path
scripts/snapshot.py:18Sensitive Portfolio Snapshots Use a Shared Temporary Directory Without File Hardening
scripts/trading212_skill.py:350Real-Money Orders Can Be Submitted Without a Code-Enforced Confirmation Boundary
requirements.txt:1Dependency Installation Is Not Reproducible or Integrity-Pinned
The skill claims broad portfolio-analysis and safety-aware trading behavior that the underlying implementation reportedly does not actually provide, while still exposing API/client and order-placement functionality. In a financial context, this mismatch can mislead users and supervising systems into trusting nonexistent analysis, validation, or guardrails before trades are proposed or executed.
The client exposes direct order-placement primitives for market and limit orders, and the skill description explicitly says it can make trade proposals and place orders. In an agent setting, the absence of an explicit confirmation/approval gate in the action path creates a real risk of unintended or prompt-induced live trades, especially when demo can be switched to live via environment configuration.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from datetime import datetime, timedelta, timezone
from pathlib import Path
# Load .env from project root before any Trading212 imports.
_env_path = Path(__file__).resolve().parents[3] / ".env"
if _env_path.exists():
from dotenv import load_dotenv
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from pathlib import Path
# Load .env from project root before any Trading212 imports.
_env_path = Path(__file__).resolve().parents[3] / ".env"
if _env_path.exists():
from dotenv import load_dotenv
load_dotenv(_env_path)
The skill can place live market or limit orders directly from parsed parameters without any built-in confirmation gate, dry-run default, or explicit safety interlock for live accounts. In an agent setting, mis-parsed prompts, prompt injection from upstream context, or accidental invocation could trigger irreversible financial transactions and losses.
The skill advertises and instructs use of capabilities that imply access to environment secrets, local files, and outbound network requests, but it does not declare any explicit tool scope or permission boundary. For a trading skill that can place orders and uses API credentials, this increases the chance of over-broad execution, secret exposure, or unintended network/file actions without transparent restriction.
The top-level description uses broad invocation language like portfolio overview, daily performance, or trade actions, which can match common finance-related requests too easily. This can cause the skill to activate in contexts where the user did not specifically intend Trading212 access, increasing the risk of unnecessary account-data exposure or escalation toward trade workflows.
The file instructs the agent to present output as a readable English summary, which imposes a language choice without user opt-in. The same policy appears again in the output format section, and no alternative language handling or justification is provided.
Example trigger phrases such as 'What should I do?' or 'Any trade suggestions?' are highly ambiguous and could be triggered by everyday conversation about markets rather than an explicit request to use this brokerage skill. In a trade-capable skill, accidental activation is more dangerous because it may expose holdings or steer the interaction toward order execution.
The instruction to present a human-readable English summary is a natural-language policy issue because it hard-codes a specific language for all users. There is no opt-in, locale selection, or documented rationale for restricting responses to English.
This reference explicitly documents a mode that can place orders and also states that snapshots are automatically written to disk, but it does not prominently warn about the real-world side effects of those actions. In a trading skill, unclear safety boundaries can lead to unintended financial transactions or silent local data persistence, especially if the caller assumes the skill is read-only or demo-only.
This file generates concrete buy/sell/reduce proposals, including quantities and rationales, but does not attach any explicit warning that the output is informational and may lead to financially impactful actions if acted on or passed to downstream order-placement components. In the context of a Trading212 skill that can also place orders, this omission increases the risk that users or automation treat these proposals as safe, authoritative trading instructions without adequate confirmation or suitability checks.
cancel_order performs a destructive account action immediately with no built-in confirmation or secondary authorization. In a trading agent context, accidental, coerced, or ambiguous cancellation requests could interfere with user strategy, remove protective orders, or cause financial loss through missed execution.
Multiple user-facing messages are emitted in Dutch, including trade descriptions, validation errors, watchlist alerts, and allocation guidance. This forces a specific language/locale without any opt-in or documented justification, which matches the language/locale policy violation criteria.
Across multiple mode descriptions, the skill repeatedly uses broad trigger examples that are not specific to Trading212, which raises the likelihood of unintentional routing. While largely a prompt-quality issue, the context makes it security-relevant because the skill can access financial data and eventually place orders.
Several user-facing message examples and descriptions are written in Dutch, such as trade event descriptions and validation errors, while the rest of the reference is in English. Because the file does not state that the skill is Dutch-only or provide language selection, it appears to impose a locale on output without user opt-in.
Alert messages and rebalance reasons in this section are also presented in Dutch, reinforcing a fixed-language behavior in otherwise English documentation. The file does not indicate that users can choose their preferred language or that the locale restriction is intentional and justified.
The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time and weakens reproducibility and supply-chain control. In a skill that can access portfolio data and place trades, unexpected dependency changes can increase operational and security risk if a newly resolved version is vulnerable or malicious.
requests>=2.31.0
python-dotenv>=1.0.0
pyyaml>=6.0.1
The manifest does not pin requests, so the actual installed version cannot be compared reliably against known advisories. In a network-facing trading skill, an unknowingly vulnerable HTTP client could expose credentials, weaken TLS/request handling, or leak sensitive information depending on the resolved version.
Using python-dotenv with only a minimum version permits non-deterministic installs and makes it difficult to verify which release is deployed. This is a supply-chain hygiene issue that becomes more important in a financial-trading skill because environment handling may include sensitive API credentials.
requests>=2.31.0
python-dotenv>=1.0.0
pyyaml>=6.0.1
Because python-dotenv is unpinned, it is not possible to verify whether deployments are using a version affected by known advisories. This matters in a skill likely to use environment variables for brokerage API keys, where a vulnerable release could mishandle or expose sensitive configuration.
An unpinned PyYAML dependency means builds may silently consume different releases, reducing reproducibility and making it harder to guarantee that only vetted versions are used. Because PyYAML has a history of security issues, this raises the chance of accidentally deploying an affected version.
requests>=2.31.0
python-dotenv>=1.0.0
pyyaml>=6.0.1
The unpinned pyyaml dependency is especially concerning because PyYAML has multiple historical deserialization and input-validation advisories, and the manifest provides no assurance that a safe version will be installed. If this skill parses YAML from untrusted or semi-trusted sources, a vulnerable version could increase the risk of code execution or other unsafe parsing outcomes.
The _ERROR_MESSAGES mapping contains fixed Dutch strings for common failures, and additional error text elsewhere also uses Dutch. This creates a language/locale policy issue because the skill does not offer a language choice or document that it is intentionally Dutch-only.
The manifest describes portfolio analysis, trade proposals, watchlist, history, dividends, allocation, and order placement. This file additionally reaches outside the skill directory to load a global .env file from the project root, which is a broader credential/config access capability not mentioned in the skill’s stated purpose.
No suspicious patterns detected.