T09 · Insecure Skill Coding Practices
- Location
scripts/hot_scanner.py:22- Finding
Hot Scanner exposes the complete process environment to a third-party CLI
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This finance skill is mostly purpose-aligned, but its optional social scanners use risky Twitter/X session-token handling and pass broad local environment data to a third-party CLI.
Review this before installing if you plan to use Hot Scanner or Rumor Scanner. Avoid putting Twitter/X session cookies in a project .env, do not grant Terminal Full Disk Access unless you fully understand the risk, and run the social scanners only in an environment without unrelated API keys or cloud credentials. The basic stock, dividend, local portfolio, and watchlist functions are aligned with the skill's purpose, but the optional social integration should be treated as high-risk.
scripts/hot_scanner.py:22Hot Scanner exposes the complete process environment to a third-party CLI
scripts/rumor_scanner.py:30Rumor Scanner exposes unrelated credentials to the Bird CLI
SKILL.md:152Executable third-party dependencies are installed or resolved without immutable version pinning
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
This mismatch specifically includes invocation of an external CLI for Twitter/X, use of additional third-party sources, and local cache writes that are not clearly declared in the skill's stated scope. That increases risk because external subprocess execution and extra network destinations expand the attack surface, may leak data to unreviewed services, and can bypass assumptions that the skill only uses Yahoo Finance.
This mismatch specifically includes invocation of an external CLI for Twitter/X, use of additional third-party sources, and local cache writes that are not clearly declared in the skill's stated scope. That increases risk because external subprocess execution and extra network destinations expand the attack surface, may leak data to unreviewed services, and can bypass assumptions that the skill only uses Yahoo Finance.
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 documentation explicitly instructs users to manually extract browser cookies from x.com and reuse them for CLI authentication. Reusing web session cookies outside the browser bypasses safer authentication boundaries and creates a direct credential-handling workflow that can enable account compromise if the tokens are intercepted, copied, stored insecurely, or reused by malware.
The .env example documents placement of live authentication material inside the skill directory, which is a common source of accidental exposure through source control, archive sharing, backups, and local file disclosure. In this skill's context, the credentials are not low-risk API keys but active session tokens, making mishandling more dangerous than typical configuration secrets.
Create .env file in the skill directory:
# /path/to/stock-analysis/.env
AUTH_TOKEN=your_auth_token_here
CT0=your_ct0_token_here
The script automatically reads a local .env file and imports arbitrary key-value pairs into its process environment without restricting scope or feature need. On its own this is risky configuration handling, and in this file it becomes more dangerous because those environment variables are later forwarded to an external subprocess, potentially exposing stored credentials.
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:
The presence and automatic parsing of .env-based credentials/config makes the process a collector of local secrets beyond what is required for basic market-data retrieval. Combined with subprocess inheritance later in the code, this creates a practical path for accidental credential exposure to the external CLI.
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 full process environment into a subprocess exposes all inherited secrets, tokens, and configuration values to an external binary that is not necessary to trust with broad access. In this skill, that risk is amplified because the code also auto-loads arbitrary .env entries, making credential leakage to the bird CLI plausible if the binary is compromised, replaced, or overly permissive.
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
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# 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."""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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 parent environment and passing it to a subprocess unnecessarily exposes all available environment variables to the Bird CLI, including unrelated secrets. If the external tool is compromised, replaced, verbose in logs, or behaves unexpectedly, broad credential exposure becomes possible.
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 os.environ.copy() has the same risk profile: it hands the full environment to an external executable for convenience rather than necessity. In an automation/agent setting, that increases blast radius because CI tokens, cloud credentials, or other secrets may be present in the environment even if this script does not need them.
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 plan explicitly includes Mixpanel/Amplitude, Sentry, and custom KPI tracking, but it does not mention any user-facing consent flow, privacy notice timing, telemetry controls, or minimization of sensitive financial/behavioral data. In a consumer finance app, analytics can expose portfolio behavior, account identifiers, or device-linked usage patterns, creating privacy and compliance risk if collected without clear disclosure and opt-in/opt-out controls.
The README instructs users to extract Twitter/X session tokens from browser developer tools and place them into a local .env file, but it does not clearly warn that these are sensitive authentication credentials equivalent to session secrets. This encourages insecure handling of live account tokens and creates risk of account takeover if the tokens are exposed through shell history, dotfile sync, backups, logs, screenshots, or repository commits.
The skill advertises and documents capabilities that imply shell execution, network access, local file reads/writes, and optional credential handling, but it does not declare any explicit tool scope or permission boundaries. This is dangerous because users and hosting platforms cannot accurately constrain what the skill may access, increasing the risk of over-privileged execution and unintended data exposure.
The skill instructs users to create a local .env file containing Twitter/X authentication tokens without a clear warning about credential sensitivity, storage risks, or least-privilege handling. This is dangerous because users may place long-lived secrets in insecure locations, accidentally commit them, or expose them to other tools running in the same environment.
The documentation tells users to grant Terminal Full Disk Access in order to let the bird CLI read browser cookies, but it does not explain the security implications of granting broad filesystem access to a terminal process. This materially increases credential theft risk because any terminal-invoked tool, shell script, or compromised dependency may gain access to sensitive local data well beyond Twitter/X authentication.
The skill documentation instructs users to store highly sensitive Twitter/X session credentials (AUTH_TOKEN and CT0) in a local .env file or environment variables without warning that these values are effectively session cookies that can enable account access. Users may commit the .env file, leak values through process inspection, logs, backups, or shell history, leading to account takeover.
The usage guide documents commands that create and modify portfolios without clearly warning that they persist user data locally. In an agent skill context, a model could invoke these examples as actionable steps, causing unintended state changes to a user's tracked assets or saved data without informed consent.
The watchlist commands add, remove, and enable alert behavior without warning that they modify persistent watchlist state and may trigger notifications. In an agent-driven environment, this can lead to unauthorized preference changes, unwanted alerts, or silent accumulation of tracked symbols if the agent follows examples literally.
The module docstring says this is 'Stock analysis using Yahoo Finance data,' but the code also fetches Google News RSS headlines for crisis/geopolitical signals and queries SEC EDGAR Form 4 filings for insider trading analysis. Those are materially different data sources and behaviors than the file-level description advertises.
No suspicious patterns detected.