T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/hot_scanner.py:22- Finding
Excessive environment-variable disclosure to the third-party bird executable in Hot Scanner
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly a coherent stock-analysis tool, but its optional Twitter/X scanners handle live session cookies and expose the full environment to an external CLI.
Install only after reviewing the optional Twitter/X features. Avoid placing live X session cookies in the skill directory, avoid granting Terminal Full Disk Access for this workflow, and prefer running hot scans with --no-social unless you trust the bird executable and can isolate credentials. Treat portfolio and watchlist files as sensitive local financial data.
scripts/hot_scanner.py:22Excessive environment-variable disclosure to the third-party bird executable in Hot Scanner
scripts/rumor_scanner.py:30Excessive environment-variable disclosure to the third-party bird executable in Rumor Scanner
scripts/analyze_stock.py:2Mutable and unverified third-party dependencies create supply-chain execution risk
README.md:143Live X session credentials are stored in an unprotected plaintext project file
scripts/portfolio.py:43Portfolio and watchlist financial data are written without restrictive file 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
This variant of the mismatch is more serious because it includes undeclared use of additional third-party sources and an external CLI/subprocess for Twitter/X, plus local cache writes. Undeclared subprocess execution and multi-source data collection materially expand the attack surface and can lead to unexpected code execution paths, credential use, and persistence on the host.
This variant of the mismatch is more serious because it includes undeclared use of additional third-party sources and an external CLI/subprocess for Twitter/X, plus local cache writes. Undeclared subprocess execution and multi-source data collection materially expand the attack surface and can lead to unexpected code execution paths, credential use, and persistence on the host.
This variant of the mismatch is more serious because it includes undeclared use of additional third-party sources and an external CLI/subprocess for Twitter/X, plus local cache writes. Undeclared subprocess execution and multi-source data collection materially expand the attack surface and can lead to unexpected code execution paths, credential use, and persistence on the host.
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
Placing authentication tokens in a .env file inside the skill directory creates a common path for accidental disclosure via source control, backups, artifact collection, support bundles, or permissive file sharing. In this skill context, the values are not low-risk API keys but session-equivalent X/Twitter tokens, so leakage could directly compromise a user's account.
Create .env file in the skill directory:
# /path/to/stock-analysis/.env
AUTH_TOKEN=your_auth_token_here
CT0=your_ct0_token_here
Accessing a repository .env file is sensitive because such files commonly contain API keys, tokens, and other credentials. In this context, the risk is elevated because the script not only reads the file but exports all values into the runtime environment before performing network operations and subprocess execution.
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 .env existence check is part of a credential-loading flow that treats all repository secrets as available to the script. While checking for the file is not harmful alone, in this implementation it enables broad credential access that later crosses process boundaries to an external CLI, making the overall pattern dangerous.
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:
os.environ.copy() harvests the full process environment and passes it to the external bird CLI. In this file, that environment may already contain secrets imported from the repository .env, so the subprocess receives far more credentials than necessary and could leak them through logs, crash reports, plugins, or compromise of the external binary.
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 local .env file for credentials is not automatically malicious, but in this script it is part of a broader pattern of credential ingestion for an external CLI. The danger comes from coupling secret access with downstream subprocess execution, which expands the trust boundary and may expose credentials beyond their intended use.
# 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 load_env routine accesses the .env file directly, enabling the skill to ingest local credentials. In context, this is more concerning because the same script forwards environment data to an external command, so local secret access is not confined to in-process use.
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 process environment after loading .env and then supplying it to an external CLI can expose all available environment secrets to that child process. In an agent-skill context, this is more dangerous because the manifest does not strongly justify broad credential access, and compromise or unexpected behavior in the Bird CLI could leak tokens or API keys.
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 environment copy repeats the same broad secret-exposure pattern in another code path. Any sensitive variables present in the parent process or imported from .env are unnecessarily handed to the external binary, increasing risk of credential leakage or abuse.
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 product analytics and Sentry error tracking, but the document does not mention any user-facing notice, consent flow, or opt-out controls for behavioral telemetry and error-data collection. In a consumer finance app, telemetry can reveal sensitive interests, holdings patterns, and usage behavior, creating privacy and compliance risk if users are tracked without adequate disclosure.
The README tells users to extract authentication cookies/tokens from their browser DevTools and place them into a local .env file for Twitter/X access. Session cookies such as AUTH_TOKEN and CT0 are highly sensitive credentials; encouraging manual extraction and storage without strong warnings, scoping guidance, or safer alternatives increases the risk of account compromise, token leakage via shell history/files, and misuse by other local processes or users.
The skill advertises executable commands that use shell, network access, environment data, and persistent local storage, but it declares no explicit tool scope or permissions. This creates a trust and review gap: a caller may assume the skill is read-only or limited to Yahoo Finance, while it can invoke external programs, access remote services, and write local files.
The documentation instructs users to grant Terminal Full Disk Access in order to let a third-party CLI access browser-stored X/Twitter session material, but it does not warn about the broad privilege being granted or safer alternatives. Full Disk Access materially expands what Terminal and any subprocess it launches can read, increasing the blast radius if the environment, shell profile, or installed tools are compromised.
The docs instruct users to manually extract auth_token and ct0 from browser cookies and store them for reuse, effectively converting active session cookies into portable credentials. Those tokens can enable account/session hijacking if exposed through shell history, logs, screenshots, repo commits, backups, or other local compromise, and the docs do not treat them as sensitive secrets or warn users about handling and revocation.
The module docstring and CLI description present this as stock analysis using Yahoo Finance data, but the code also fetches Google News RSS for crisis/geopolitical alerts, CNN Fear & Greed data, and SEC Form 4 insider-trading data. Those extra external intelligence sources materially affect scores, caveats, and confidence, so this is more than an implementation detail of Yahoo Finance retrieval.
The script sends user-supplied tickers and portfolio holdings to multiple third-party services (Yahoo Finance, Google News RSS, Fear & Greed, SEC EDGAR) without prominently warning users in the CLI help or usage text. In a portfolio-analysis context, this can leak sensitive investment interests or holdings metadata to external providers, which is a real privacy and data-governance issue even if the data is not highly confidential by default.
This function reaches out to Google News RSS, parses general finance/economy headlines, and uses keyword heuristics to attach breaking-news alerts to outputs. That is a distinct news-intelligence capability rather than an obvious requirement of a Yahoo Finance stock-analysis script as documented in this file.
The insider-activity path uses edgartools to identify the client and retrieve Form 4 filings from SEC EDGAR, then scores recent insider buying/selling as part of sentiment. That goes beyond the script's stated Yahoo Finance-based analysis and introduces another external regulatory-data collection capability.
No suspicious patterns detected.