Back to skill

Security audit

csig-skill-0625

Security checks across malware telemetry and agentic risk

Overview

This appears to be a legitimate stock and crypto analysis skill, but its optional social scanning handles live X/Twitter session cookies and exposes broad local environment secrets to an external CLI.

Review carefully before installing. The safest path is to use stock analysis, portfolio, watchlist, and hot scanning with --no-social, and avoid providing X/Twitter session cookies unless you understand that AUTH_TOKEN and CT0 can act like account access. Do not put unrelated secrets in the skill .env file, restrict file permissions, use a dedicated low-risk X account if social scanning is needed, and treat BUY/HOLD/SELL output as informational rather than trading advice.

SkillSpector

By NVIDIA
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
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (26)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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
                    )
Confidence
86% confidence
Finding
result = subprocess.run( [bird_bin, "search", query, "-n", "15", "--json"], capture_output=True, text=True, timeout=30, env=env

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and demonstrates shell execution, network access, and reads/writes to local files, but does not declare corresponding permissions. That mismatch is dangerous because users and orchestrators may grant the skill more trust than warranted, while the skill can access external data sources and persist data locally without explicit permission transparency.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The code loads every key from the project `.env` file into process environment variables without scoping or disclosure. In this same script, the full environment is later forwarded to an external CLI, so unrelated secrets can be exposed to another program even though they are not needed for stock scanning.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
Twitter/X scanning is implemented by invoking the external `bird` CLI, which introduces a separate executable into the trust chain. In an agent skill context, this is riskier than normal application code because the runtime may contain sensitive credentials and the binary may not be controlled or audited with the same rigor as the Python source.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The script reads arbitrary secrets from a local .env file into process environment variables, then later forwards that environment to an external Bird CLI. This creates unnecessary credential exposure to another program and potentially to any downstream network activity that CLI performs, increasing the blast radius of unrelated secrets.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The plan explicitly includes product analytics, error tracking, and push notifications, but does not pair them with a clear user-facing consent/notice model beyond a generic privacy-policy mention. In a retail investing app handling portfolio data, behavioral telemetry and notification processing can expose sensitive financial interests and device/user identifiers if collected or shared without transparent disclosure and consent controls.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The README explicitly instructs users to extract live X/Twitter session cookies from browser developer tools and store them in a local .env file for CLI authentication. Session cookies are effectively bearer credentials; if copied, mishandled, logged, committed, or read by other local processes, they can enable account takeover or unauthorized access without a password, and the README provides no meaningful warning about secure handling, scope, expiration, or revocation.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The Twitter/X setup instructs users to place AUTH_TOKEN and CT0 in a local .env file without any warning about secure storage, file permissions, accidental commits, or token scope. These are live authentication secrets, and insecure handling can lead to account compromise, unauthorized access, or leakage through logs, backups, or source control.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The document introduces a clear BUY / HOLD / SELL output early as part of the product value proposition before presenting limitations and 'not financial advice' caveats much later. In an investment-analysis skill, this can encourage users to over-trust actionable recommendations without seeing an immediate risk warning, increasing the chance of unsafe financial decisions even though the content is not overtly malicious.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation instructs users to extract and store live Twitter/X session credentials (`auth_token` and `ct0`) in a local `.env` file or shell environment, but it does not warn that these are highly sensitive session tokens equivalent to account access. In a skill intended for automation and scheduled execution, this increases the chance that tokens are left on disk, committed to repos, exposed in shell history, or reused insecurely, enabling account compromise or unauthorized API actions if leaked.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The script performs multiple outbound network requests to third-party services without a clear, user-facing disclosure or consent mechanism. In an agent skill context, this can leak user interests, watchlists, portfolio holdings, and analysis targets to external providers unexpectedly, creating a privacy and data-governance risk even if the requests themselves are legitimate.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Loading `.env` contents without user-facing disclosure is a real concern in an agent skill because users may not expect the skill to ingest local secrets at all. Even if the variables are not immediately exfiltrated here, silently broadening access to local credentials increases the blast radius of any later bug or external tool invocation.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The code silently loads credentials and passes the full environment to an external CLI without any user-facing disclosure. In a skill context, this is risky because users may not expect their local secrets to be exposed to a helper binary during stock analysis operations.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
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
Confidence
99% confidence
Finding
os.environ.copy()

Env Variable Harvesting

High
Category
Data Exfiltration
Content
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)
Confidence
97% confidence
Finding
os.environ.copy()

Env Variable Harvesting

High
Category
Data Exfiltration
Content
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)
Confidence
97% confidence
Finding
os.environ.copy()

Unvalidated Output Injection

High
Category
Output Handling
Content
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
                    )
Confidence
95% confidence
Finding
subprocess.run( [bird_bin, "search", query, "-n", "15", "--json"], capture_output

Unvalidated Output Injection

High
Category
Output Handling
Content
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)
            
            if result.returncode == 0 and result.stdout:
                try:
Confidence
95% confidence
Finding
subprocess.run(cmd, capture_output

Unvalidated Output Injection

High
Category
Output Handling
Content
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)
            
            if result.returncode == 0 and result.stdout:
                try:
Confidence
95% confidence
Finding
subprocess.run(cmd, capture_output

Credential Access

High
Category
Privilege Escalation
Content
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:
Confidence
94% confidence
Finding
.env

Credential Access

High
Category
Privilege Escalation
Content
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:
Confidence
94% confidence
Finding
.env"

Self-Modification

High
Category
Rogue Agent
Content
- [ ] 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
Confidence
85% confidence
Finding
Update SKILL

Self-Modification

High
Category
Rogue Agent
Content
- Extreme risk (80-100): -0.5 (bearish)
- [ ] Add to sentiment analysis as 6th indicator
- [ ] Test with historical crisis periods
- [ ] Update SKILL.md with geopolitical indicator

**Expected Impact**:
- Early warning for market-wide risk events
Confidence
85% confidence
Finding
Update SKILL

Tool Parameter Abuse

High
Category
Tool Misuse
Content
GET  /portfolios
   POST /portfolios
   PUT  /portfolios/{id}
   DELETE /portfolios/{id}

   GET  /portfolios/{id}/assets
   POST /portfolios/{id}/assets
Confidence
80% confidence
Finding
DELETE /portfolios/{id}

Tool Parameter Abuse

High
Category
Tool Misuse
Content
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
Confidence
80% confidence
Finding
DELETE /portfolios/{id}/assets/{ticker}

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.