Back to skill

Security audit

0605-tosr2-cisg-02

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/rumor_scanner.py:30
Finding

Excessive environment-variable disclosure to the third-party bird executable in Rumor Scanner

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/analyze_stock.py:2
Finding

Mutable and unverified third-party dependencies create supply-chain execution risk

Content
View full analysis
=3.10" # dependencies = [ # "yfinance>=0.2.40", # "pandas>=2.0.0", # "fear-and-greed>=0.4", # "edgartools>=2.0.0", # "feedparser>=6.0.0", # ] # /// ``` The documentation also instructs users to install a mutable global npm package: ```bash npm install -g @steipete/bird ``` Other scripts use similarly open-ended constraints, including: ```python # dependencies = ["yfinance>=0.2.40"] ``` ### Technical Analysis The Python dependency metadata specifies only lower bounds and does not include a committed lockfile, exact reviewed versions, or integrity hashes. Running the documented `uv run` commands may therefore resolve newer dependency releases than those originally reviewed. The X integration also instructs users to install `@steipete/bird` globally without an exact version. A future package release, compromised publisher account, registry compromise, or malicious transitive dependency could introduce arbitrary code. This risk is amplified because the scanners pass sensitive authentication values—and currently the complete process environment—to `bird`. This finding does not establish that any current dependency is malicious. The vulnerability is the absence of reproducible, integrity-verified dependency resolution for code that executes with user privileges. ### Attack Path 1. An upstream package publisher account, package release, or transitive dependency is compromised. 2. The attacker publishes a malicious version satisfying the broad minimum-version constraint. 3. A user runs a documented `uv run` command or installs the unversioned global npm p ...[truncated 740 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:143
Finding

Live X session credentials are stored in an unprotected plaintext project file

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/portfolio.py:43
Finding

Portfolio and watchlist financial data are written without restrictive file permissions

Content
View full analysis
Path: """Get the portfolio storage path.""" # Use ~/.clawdbot/skills/stock-analysis/portfolios.json state_dir = os.environ.get( "CLAWDBOT_STATE_DIR", os.path.expanduser("~/.clawdbot") ) portfolio_dir = Path(state_dir) / "skills" / "stock-analysis" portfolio_dir.mkdir(parents=True, exist_ok=True) return portfolio_dir / "portfolios.json" ``` ```python def _save(self) -> None: """Save portfolios to disk with atomic write.""" if self._data is None: return # Ensure directory exists self.path.parent.mkdir(parents=True, exist_ok=True) # Atomic write: write to temp file, then rename tmp_path = self.path.with_suffix(".tmp") try: with open(tmp_path, "w", encoding="utf-8") as f: json.dump(self._data, f, indent=2) tmp_path.replace(self.path) except Exception: if tmp_path.exists(): tmp_path.unlink() raise ``` The watchlist uses the same default-permission behavior: ```python # Storage WATCHLIST_DIR = Path.home() / ".clawdbot" / "skills" / "stock-analysis" WATCHLIST_FILE = WATCHLIST_DIR / "watchlist.json" ``` ```python def ensure_dirs(): """Create storage directories.""" WATCHLIST_DIR.mkdir(parents=True, exist_ok=True) def save_watchlist(items: list[WatchlistItem]): """Save watchlist to file.""" ensure_dirs() data = [asdict(item) for item in items] WATCHLIST_FILE.write_text(json.dumps(data, indent=2)) ``` ### Technical Analysis Portfolio files contain holdings, quantities, cost bases, and timestamps. Watchlist files may contain target prices, stop prices, signal preferences, and user notes. These constitute sensitive personal financial i ...[truncated 1199 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (54)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

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).

Content

Scanner excerpt · App-Plan.md (reported line 114)May include surrounding context.

md
GET  /portfolios
   POST /portfolios
   PUT  /portfolios/{id}
   DELETE /portfolios/{id}

   GET  /portfolios/{id}/assets
   POST /portfolios/{id}/assets

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

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).

Content

Scanner excerpt · App-Plan.md (reported line 119)May include surrounding context.

md
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 Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

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).

Content

Scanner excerpt · App-Plan.md (reported line 126)May include surrounding context.

md
GET  /alerts
   POST /alerts
   DELETE /alerts/{id}

   GET  /user/subscription
   POST /user/subscription/upgrade

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

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.

Content

Scanner excerpt · TODO.md (reported line 88)May include surrounding context.

md
- [ ] 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

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

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.

Content

Scanner excerpt · TODO.md (reported line 193)May include surrounding context.

md
- [ ] 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

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

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.

Content

Scanner excerpt · docs/HOT_SCANNER.md (reported line 149)May include surrounding context.

Create .env file in the skill directory:

bash
# /path/to/stock-analysis/.env
AUTH_TOKEN=your_auth_token_here
CT0=your_ct0_token_here

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

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.

Content

Scanner excerpt · scripts/hot_scanner.py (reported line 22)May include surrounding context.

python
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:

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

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.

Content

Scanner excerpt · scripts/hot_scanner.py (reported line 23)May include surrounding context.

python
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:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
98% confidence
Finding

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.

Content

Scanner excerpt · scripts/hot_scanner.py (reported line 387)May include surrounding context.

python
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

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

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.

Content

Scanner excerpt · scripts/rumor_scanner.py (reported line 30)May include surrounding context.

python
# 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."""

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

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.

Content

Scanner excerpt · scripts/rumor_scanner.py (reported line 33)May include surrounding context.

python
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('#'):

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
96% confidence
Finding

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.

Content

Scanner excerpt · scripts/rumor_scanner.py (reported line 79)May include surrounding context.

python
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)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
96% confidence
Finding

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.

Content

Scanner excerpt · scripts/rumor_scanner.py (reported line 132)May include surrounding context.

python
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)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.