T09 · Insecure Skill Coding Practices
- Location
scripts/hot_scanner.py:22- Finding
Hot Scanner exposes the complete process environment to a network-capable third-party executable
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its stock-analysis purpose, but its Twitter features ask users to expose live X session cookies and pass broad environment secrets to an external CLI.
Review before installing. Use --no-social for hot scans unless you are comfortable giving a third-party CLI access to X session credentials, avoid granting Terminal Full Disk Access, do not place unrelated secrets in the skill .env, and treat portfolio/watchlist files as sensitive local financial data.
scripts/hot_scanner.py:22Hot Scanner exposes the complete process environment to a network-capable third-party executable
scripts/rumor_scanner.py:33Rumor Scanner exposes the complete process environment to the Twitter CLI
scripts/hot_scanner.py:364Unpinned globally installed Twitter dependency receives live session credentials
docs/HOT_SCANNER.md:132Documentation recommends granting Terminal unnecessary Full Disk Access
scripts/portfolio.py:111Portfolio and watchlist financial data are stored without explicit restrictive permissions
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
GET /portfolios
POST /portfolios
PUT /portfolios/{id}
DELETE /portfolios/{id}
GET /portfolios/{id}/assets
POST /portfolios/{id}/assets
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
GET /portfolios/{id}/assets
POST /portfolios/{id}/assets
PUT /portfolios/{id}/assets/{ticker}
DELETE /portfolios/{id}/assets/{ticker}
GET /portfolios/{id}/performance?period=weekly
GET /portfolios/{id}/summary
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
GET /alerts
POST /alerts
DELETE /alerts/{id}
GET /user/subscription
POST /user/subscription/upgrade
The skill description claims a large set of capabilities and trusted data-source expectations, while the documented behavior appears inconsistent and includes undeclared external sources. This is dangerous because users and orchestrators may make trust decisions based on inaccurate declarations, leading to unexpected data exfiltration, network access, or automation behavior outside the stated scope.
The skill description claims a large set of capabilities and trusted data-source expectations, while the documented behavior appears inconsistent and includes undeclared external sources. This is dangerous because users and orchestrators may make trust decisions based on inaccurate declarations, leading to unexpected data exfiltration, network access, or automation behavior outside the stated scope.
The skill description claims a large set of capabilities and trusted data-source expectations, while the documented behavior appears inconsistent and includes undeclared external sources. This is dangerous because users and orchestrators may make trust decisions based on inaccurate declarations, leading to unexpected data exfiltration, network access, or automation behavior outside the stated scope.
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
- [ ] Add timeout per indicator (10s max)
- [ ] Test with multiple stocks in sequence
- [ ] Measure actual runtime improvement
- [ ] Update SKILL.md with new runtime (target: 3-4s)
**Expected Impact**:
- Reduce runtime from 6-10s to 3-4s per stock
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
- [ ] Add timeout per indicator (10s max)
- [ ] Test with multiple stocks in sequence
- [ ] Measure actual runtime improvement
- [ ] Update SKILL.md with new runtime (target: 3-4s)
**Expected Impact**:
- Reduce runtime from 6-10s to 3-4s per stock
The .env example directs users to place active Twitter/X authentication tokens in a file within the skill directory, creating a concrete pathway for sensitive credential exposure through source control, backups, logs, or accidental file sharing. Because these values are session tokens rather than low-privilege API keys, compromise could allow unauthorized access to the associated X account until revoked or expired.
Create .env file in the skill directory:
# /path/to/stock-analysis/.env
AUTH_TOKEN=your_auth_token_here
CT0=your_ct0_token_here
The code explicitly targets a .env file and imports its contents, which commonly contain API keys, tokens, or credentials. While loading secrets is sometimes legitimate, here it creates unnecessary credential exposure because the script later runs an external program with inherited environment state.
from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor, as_completed
# Load .env file if exists
ENV_FILE = Path(__file__).parent.parent / ".env"
if ENV_FILE.exists():
with open(ENV_FILE) as f:
Opening and parsing a project-level .env file is credential-access behavior that increases risk when combined with later subprocess execution. The danger is contextual: a market scanner does not need broad access to all local secrets, so this exceeds least-privilege expectations.
from concurrent.futures import ThreadPoolExecutor, as_completed
# Load .env file if exists
ENV_FILE = Path(__file__).parent.parent / ".env"
if ENV_FILE.exists():
with open(ENV_FILE) as f:
for line in f:
Copying the entire environment is a form of secret harvesting because it collects all available environment variables, including credentials unrelated to this feature. In this file, that harvested data is immediately provided to an external subprocess, making accidental or malicious exfiltration much more plausible.
for category, query in searches:
try:
env = os.environ.copy()
result = subprocess.run(
[bird_bin, "search", query, "-n", "15", "--json"],
capture_output=True, text=True, timeout=30, env=env
Referencing a repository-local .env for runtime secrets is not inherently malicious, but in this script it supports external CLI authentication and broad environment propagation. That creates a real credential-handling risk because secrets are pulled from disk and made available to another executable without strict controls.
# Bird CLI path
BIRD_CLI = "/home/clawdbot/.nvm/versions/node/v24.12.0/bin/bird"
BIRD_ENV = Path(__file__).parent.parent / ".env"
def load_env():
"""Load environment variables from .env file."""
The .env parsing logic reads every key/value pair and places it into os.environ, which is later inherited by the Bird CLI. This broad secret access is dangerous because it exceeds least privilege and can expose credentials unrelated to rumor scanning.
BIRD_ENV = Path(__file__).parent.parent / ".env"
def load_env():
"""Load environment variables from .env file."""
if BIRD_ENV.exists():
for line in BIRD_ENV.read_text().splitlines():
if '=' in line and not line.startswith('#'):
Copying the full environment and passing it to an external CLI can leak unrelated secrets, tokens, and service credentials into a child process that does not need them. In a tool-running agent environment, this broad inheritance substantially increases blast radius if the CLI is compromised, logs its environment, or forwards telemetry.
for query in queries[:4]: # Limit to avoid rate limits
try:
cmd = [BIRD_CLI, 'search', query, '-n', '10', '--json']
env = os.environ.copy()
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, env=env)
This second occurrence repeats the same risky pattern of forwarding the entire environment to an external binary. Because the skill context already includes local .env ingestion, the combination makes credential overexposure more dangerous than ordinary environment inheritance.
for query in queries[:3]:
try:
cmd = [BIRD_CLI, 'search', query, '-n', '15', '--json']
env = os.environ.copy()
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, env=env)
The manifest describes a stock and crypto analysis skill with portfolio/watchlist features, but this document proposes transforming it into a commercial mobile product with backend services, authentication, cloud infrastructure, and monetization. Those are materially broader product behaviors than an analysis skill and represent a semantic scope expansion rather than an implementation detail.
Stripe integration, webhook handling, subscription tier changes, and in-app purchase flows are commercial billing capabilities, not direct requirements of stock or crypto analysis. The manifest does not state any billing or payment-processing purpose, so this capability is contextually outside the justified scope.
The roadmap includes Mixpanel/Amplitude and Sentry for analytics and error tracking but does not mention any user-facing disclosure, consent flow, or privacy controls tied to that telemetry. In a retail-investor app handling account, portfolio, and behavioral data, undisclosed tracking can lead to privacy violations, regulatory exposure, and accidental leakage of sensitive user information into third-party services.
The README explicitly instructs users to extract AUTH_TOKEN and CT0 cookies from browser DevTools and store them in a .env file, which are effectively session credentials for the user's X account. This encourages insecure handling of sensitive authentication material and increases the risk of account takeover if the tokens are exposed through shell history, logs, backups, repo commits, or weak local file protections.
The skill advertises shell, network, filesystem, and environment-dependent behavior through documented commands and metadata, but it does not declare any explicit tool scope or permissions boundary. This is dangerous because a host agent may grant broader capabilities than users expect, making command execution, network access, and local file writes occur without clear least-privilege constraints.
The skill instructs users to place Twitter/X authentication material in a local .env file but does not include any warning about secret sensitivity, storage hygiene, or accidental disclosure. This is dangerous because users may store live session tokens insecurely, commit them to source control, or expose them to other tools, enabling account takeover or unauthorized API access.
The documentation instructs users to obtain Twitter/X session credentials from browser cookies and store them in a local .env file or environment variables, but it does not clearly warn that these are highly sensitive session tokens that can grant account access. In the context of an agent skill that may be run, shared, or automated, encouraging manual extraction and storage of live auth tokens increases the risk of credential theft, accidental disclosure, or account compromise.
The usage guide shows portfolio creation, adding holdings, and watchlist modification commands without clearly warning that they persist and mutate local user data. In an agent-driven context, users may assume these are read-only analysis examples and unintentionally create, alter, or overwrite portfolio/watchlist state, leading to integrity issues, privacy exposure, or confusion in downstream automation.
The module docstring and CLI description frame this script as 'Stock analysis using Yahoo Finance data' and 'Analyze stocks using Yahoo Finance data'. In practice, the code also fetches Google News RSS for breaking news and uses EDGAR/SEC Form 4 filings for insider trading sentiment, which are materially different data sources and broaden the behavior beyond the stated Yahoo Finance scope.
No suspicious patterns detected.