Back to skill

Security audit

Skill

Security checks for vulnerabilities and agentic risk

Overview

InvestorClaw is a coherent local portfolio-analysis skill, but it exposes sensitive unauthenticated management surfaces and has install/runtime weaknesses users should review before installing.

Install only on a personal machine unless you add your own authentication and network controls. Prefer the bundled compose.yml over any curl-from-main install path, keep ports bound to loopback, do not expose the dashboard/MCP ports remotely without an auth proxy, and avoid leaving the service running while browsing untrusted sites. Treat provider keys and uploaded portfolio files as sensitive, and rotate keys if you suspect any local endpoint was reachable by another user, browser page, or container.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
bridge/investorclaw_bridge/serve.py:120
Finding
Unauthenticated sensitive management interfaces lack CSRF and remote-access safeguards<![CDATA[ ## Vulnerability Details **File Location**: `bridge/investorclaw_bridge/serve.py:120-121, 240-269`; `bridge/investorclaw_bridge/dashboard.py:1522-1619`; `bridge/investorclaw_bridge/mcp/transport.py:239-254` **Vulnerability Type**: Missing authentication, missing CSRF protection, and disabled DNS-rebinding protection **Risk Level**: High ### Vulnerable Code ```python mcp_bind = os.environ.get("IC_MCP_BIND", "0.0.0.0:8090") dashboard_bind = os.environ.get("IC_DASHBOARD_BIND", "0.0.0.0:8092") ``` ```python _allowed_hosts = os.environ.get("MCP_ALLOWED_HOSTS", "").strip() if _allowed_hosts: _sec = TransportSecuritySettings( enable_dns_rebinding_protection=True, allowed_hosts=[h.strip() for h in _allowed_hosts.split(",") if h.strip()], ) else: _sec = TransportSecuritySettings(enable_dns_rebinding_protection=False) mcp_app = FastMCP("investorclaw", transport_security=_sec) ``` ```python @app.post("/dashboard/settings/keys", include_in_schema=False) async def settings_save_key(request: Request) -> RedirectResponse: form = await request.form() name = (form.get("key_name") or "").strip() value = (form.get("key_value") or "").strip() if not name or not value: return RedirectResponse( url="/dashboard/settings?message=Missing+name+or+value", status_code=303, ) import inspect as _inspect result = set_key(name, value) if _inspect.iscoroutine(result): result = await result ``` ```python @app.post("/dashboard/upload", include_in_schema=False) async def upload_portfolio(request: Request) -> RedirectResponse: """Multipart upload — write to /data/portfolios/, then trigger setup.""" from urllib.parse import quote try: form = await request.form() except Exception as e: return RedirectResponse( url=f"/dashboard/settings?message={quote('Upload parse failed: ' + str(e))}", status_code=303, ) ``` ```python ...[truncated 2964 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require authentication for every endpoint except narrowly scoped health and version checks. 2. Support a mandatory bearer token or authenticated session for MCP, REST, setup, dashboard, upload, key-management, regeneration, and response-management routes. 3. Add CSRF tokens to all browser forms and validate `Origin` and `Referer` headers for state-changing requests. 4. Use `SameSite=Strict`, `HttpOnly`, and `Secure` attributes if cookie-based sessions are introduced. 5. Keep MCP DNS-rebinding protection enabled and provide an explicit allowlist for `localhost`, loopback addresses, and approved Compose service names. 6. Refuse startup on a non-loopback bind address unless authentication is configured. 7. Add rate limits and concurrency limits to refresh, initialization, upload, and regeneration operations. 8. Document reverse-proxy requirements, including TLS and authentication, for remote deployments. 9. Add integration tests proving that unauthenticated mutations, invalid CSRF tokens, unapproved Host headers, and unapproved Origins are rejected. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
bridge/investorclaw_bridge/setup_api.py:129
Finding
Multiline API-key values can inject arbitrary entries into the persisted environment file<![CDATA[ ## Vulnerability Details **File Location**: `bridge/investorclaw_bridge/mcp/tools/keys.py:140-150`; `bridge/investorclaw_bridge/setup_api.py:129-153`; `bridge/investorclaw_bridge/key_resolver.py:68-84`; `bridge/investorclaw_bridge/serve.py:99-108` **Vulnerability Type**: Environment-file injection through insufficient secret-value validation **Risk Level**: High ### Vulnerable Code ```python # Normalize values updates = { name: ((value or "").strip() if isinstance(value, str) else "") for name, value in keys.items() } # Persist + mirror into environ _persist(updates) _push_into_environ(updates) ``` ```python def _save_keys(updates: dict[str, str]) -> None: """Merge updates into /data/keys.env. Empty values delete the key. Sets file mode 0600 after write.""" PORTFOLIO_DIR.parent.mkdir(parents=True, exist_ok=True) existing = _read_existing_keys() for name, value in updates.items(): if not _VALID_KEY_NAME.match(name): continue if value: existing[name] = value else: existing.pop(name, None) lines = ["# InvestorClaw v4.0 keys.env — managed by /setup", ""] for name in sorted(existing.keys()): lines.append(f"{name}={existing[name]}") lines.append("") old_umask = os.umask(0o077) try: KEYS_FILE.write_text("\n".join(lines)) finally: os.umask(old_umask) KEYS_FILE.chmod(0o600) ``` ```python for lineno, raw in enumerate(keys_env.read_text().splitlines(), start=1): line = raw.strip() if not line or line.startswith("#"): continue m = _ENV_LINE.match(line) if not m: logger.warning( "keys.load.skip_unmatched_line", path=str(keys_env), lineno=lineno ) continue key, value = m.group(1), m.group(2) if (value.startswith('"') and value.endswith('"')) or ( value.startswith("'") and value.endswith("'") ): value = value[1:-1] keys[key] = value ...[truncated 3195 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject API-key values containing `\r`, `\n`, NUL bytes, Unicode line separators, or other control characters. 2. Apply explicit maximum lengths to key names and values. 3. Reapply the provider-key allowlist when reading `/data/keys.env`; never import arbitrary names from this file. 4. Avoid copying the complete file into the process-wide environment. Build a dedicated subprocess environment containing only approved variables. 5. Serialize values through a well-tested dotenv encoder, or use a structured format such as JSON with strict schema validation and restrictive permissions. 6. Write updates through a temporary file created with exclusive flags, apply mode `0600`, `fsync` it, and atomically replace the destination. 7. Reject symbolic-link destinations or open files with no-follow semantics where supported. 8. Add regression tests using multiline values such as: - `value\nMNEMOS_BASE=https://example.invalid` - `value\r\nPATH=/tmp/attacker` - values containing NUL and Unicode line separators 9. Verify after restart that no unapproved variable can enter `os.environ`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bridge/investorclaw_bridge/setup_api.py:326
Finding
Portfolio upload endpoints allow unbounded in-memory and persistent-storage consumption<![CDATA[ ## Vulnerability Details **File Location**: `bridge/investorclaw_bridge/setup_api.py:326-357`; `bridge/investorclaw_bridge/dashboard.py:1551-1599` **Vulnerability Type**: Unbounded file upload and denial of service **Risk Level**: Medium ### Vulnerable Code ```python @router.post("/portfolio", response_class=HTMLResponse) async def upload_portfolio( portfolio_file: UploadFile = File(...), ): if not portfolio_file.filename: raise HTTPException(400, "No file selected") suffix = Path(portfolio_file.filename).suffix.lower() if suffix not in {".csv", ".xls", ".xlsx", ".pdf"}: raise HTTPException( 400, f"Unsupported file type: {suffix}. Allowed: .csv .xls .xlsx .pdf" ) PORTFOLIO_DIR.mkdir(parents=True, exist_ok=True) safe_name = Path(portfolio_file.filename).name dest = PORTFOLIO_DIR / safe_name contents = await portfolio_file.read() dest.write_bytes(contents) dest.chmod(0o600) ``` ```python @app.post("/dashboard/upload", include_in_schema=False) async def upload_portfolio(request: Request) -> RedirectResponse: form = await request.form() upload = form.get("portfolio_file") if upload is None or not getattr(upload, "filename", ""): return RedirectResponse( url="/dashboard/settings?message=No+file+selected", status_code=303, ) raw_name = os.path.basename(upload.filename) safe_name = "".join(c for c in raw_name if c.isalnum() or c in "._-") or "portfolio.upload" if len(safe_name) > 200: safe_name = safe_name[-200:] pdir = pathlib.Path(os.environ.get("IC_PORTFOLIO_DIR", "/data/portfolios")) pdir.mkdir(parents=True, exist_ok=True) dest = pdir / safe_name content = await upload.read() dest.write_bytes(content) try: dest.chmod(0o644) except OSError: pass ``` ### Technical Analysis Both endpoints call `await upload.read()` without specifying a maximum size or streami ...[truncated 1890 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce a conservative request-body and file-size limit at both the reverse-proxy and FastAPI layers. 2. Stream uploads in bounded chunks rather than calling `read()` without a limit. 3. Abort and delete partial files as soon as the configured limit is exceeded. 4. Apply consistent extension, MIME-type, and file-signature validation to both upload routes. 5. Store uploaded files with mode `0600` unless broader access is explicitly required. 6. Add per-user and global storage quotas. 7. Add request-rate limits and restrict concurrent uploads and regeneration jobs. 8. Authenticate upload endpoints and add CSRF protection. 9. Use random server-generated filenames or safe exclusive creation to avoid unintended overwrites. 10. Add tests for oversized multipart bodies, repeated uploads, disk-full behavior, malformed documents, and mismatched file signatures. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
agent-skills/claude-code/INSTALL.md:42
Finding
Installation instructions retrieve a mutable remote deployment specification and execute its selected containers<![CDATA[ ## Vulnerability Details **File Location**: `agent-skills/claude-code/INSTALL.md:42-50`; `agent-skills/claude-code/manifest-template.json:74-76` **Vulnerability Type**: Mutable remote payload retrieval followed by deployment execution **Risk Level**: Medium ### Vulnerable Code ```bash mkdir -p ~/.investorclaw curl -sSL https://raw.githubusercontent.com/ncz-os/mnemos-ic-runtime/main/compose.yml > ~/.investorclaw/compose.yml cd ~/.investorclaw docker compose up -d ``` The plugin manifest repeats the same workflow: ```json "postInstall": { "// TODO: confirm postInstall field name and message-rendering convention": null, "message": "InvestorClaw plugin installed. To finish setup, run:\n\n mkdir -p ~/.investorclaw\n curl -sSL https://raw.githubusercontent.com/ncz-os/mnemos-ic-runtime/main/compose.yml > ~/.investorclaw/compose.yml\n cd ~/.investorclaw && docker compose up -d\n\nThen open http://localhost:18092 to upload a portfolio. See INSTALL.md for full details." } ``` ### Technical Analysis The instructions retrieve `compose.yml` from the mutable `main` branch and immediately use it as a Docker deployment specification. Although this is not a literal `curl | bash` pipeline, a Compose file is executable deployment configuration: it controls image selection, entrypoints, commands, host mounts, ports, environment variables, capabilities, and privilege settings. The remote repository namespace also differs from the primary project homepage and current image organization, which makes provenance harder for users to verify. No commit pin, checksum, signature, or manual review step is required. Consequently, the effective code and privileges used during installation may change after this Skill package has been audited. ### Attack Path 1. An attacker compromises the remote repository, its `main` branch, or an account authorized to modify it. 2. The attacker changes `compose.yml` to select a malicious image, add dangerous host mounts, change comma ...[truncated 1133 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use the `compose.yml` bundled with the reviewed Skill package. 2. If remote retrieval is unavoidable, pin the URL to an immutable commit hash. 3. Publish and verify a SHA-256 checksum or signed release manifest before running Compose. 4. Display the downloaded specification and require review when it requests host mounts, elevated capabilities, privileged mode, or Docker-socket access. 5. Use a single canonical repository namespace and reconcile all homepage, repository, image, and documentation references. 6. Add CI checks that reject installation instructions referencing mutable branches. 7. Pin all container images in the Compose file by immutable digest. 8. Provide a documented verification command, such as `cosign verify`, for signed OCI images. ]]>

T08 · Insecure Dependencies

Warning
Location
bridge/pyproject.toml:14
Finding
Python dependencies and container images are not immutably pinned<![CDATA[ ## Vulnerability Details **File Location**: `bridge/pyproject.toml:14-29`; `compose.yml:41-44` **Vulnerability Type**: Unlocked dependencies and mutable container tags **Risk Level**: Medium ### Vulnerable Code ```toml dependencies = [ "fastapi>=0.115", "uvicorn[standard]>=0.32", "python-multipart>=0.0.9", "mcp>=1.4", "httpx>=0.28", "sqlalchemy>=2.0", "aiosqlite>=0.20", "pydantic>=2.10", "structlog>=24.4", ] ``` ```yaml services: ic-engine: image: ghcr.io/argonautsystems/ic-engine:4.7.2-cpu container_name: ic-engine restart: unless-stopped ``` ### Technical Analysis All Python dependencies use open-ended lower bounds. No lockfile or hash-locked requirements file is present in the audited project. A future installation may therefore resolve to package versions that were not represented during review or testing. The container image is pinned to a version-like tag but not to an immutable digest. Registry tags can be replaced, whether accidentally or after registry or maintainer compromise. Project metadata also contains inconsistent component versions across the root Skill, Compose file, runtime-specific Skills, and manifests. This makes it difficult to establish which artifact is intended and tested. No dependency-confusion or typosquatting package was confirmed during the audit. The issue is the absence of reproducible, integrity-verified dependency resolution. ### Attack Path 1. A dependency maintainer account, package registry, container registry, or project publishing account is compromised, or a future incompatible release is published. 2. The user rebuilds the bridge or pulls the tagged container image. 3. The package manager resolves an unreviewed version, or the registry serves changed content under the same image tag. 4. The new component executes inside the InvestorClaw environment. 5. It gains access to the bridge process data, network, mounted portfolio directory, configured API keys ...[truncated 662 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate and commit a lockfile containing exact transitive dependency versions. 2. Use hash verification for all downloaded Python distributions. 3. Define controlled upgrade windows and rerun security tests after dependency changes. 4. Pin the OCI image by digest, for example `image: repository@sha256:...`. 5. Sign container images and verify signatures during installation. 6. Generate and publish an SBOM for each release. 7. Add automated vulnerability scanning for Python packages and OCI images. 8. Reconcile version numbers across `SKILL.md`, `compose.yml`, runtime-specific Skills, installation manifests, and documentation. 9. Configure dependency tooling to reject unexpected package indexes and use only explicitly approved registries. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (194)

Credential Access

High
Category
Privilege Escalation
Content
InvestorClaw checks your home directory next.

```bash
~/.investorclaw/.env
FINNHUB_KEY=pk_live_xxx
NEWSAPI_KEY=xxx
FRED_API_KEY=xxx
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
names, bond metadata extraction from description strings, guided
    mapping flow)
  - `contract-output.md` — full output spec (directory layout, envelope
    format, compact vs full output rules)
  - `schema-holdings-fields.md` — per-position field reference
    (security_type, is_etf, financial_type, proxy_symbol)
  - `runtime-gemma4-consult.md` — gemma4-consult Ollama setup for the
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
names, bond metadata extraction from description strings, guided
    mapping flow)
  - `contract-output.md` — full output spec (directory layout, envelope
    format, compact vs full output rules)
  - `schema-holdings-fields.md` — per-position field reference
    (security_type, is_etf, financial_type, proxy_symbol)
  - `runtime-gemma4-consult.md` — gemma4-consult Ollama setup for the
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The RFC explicitly proposes one-click writing of agent configuration files, which is a sensitive persistence and tool-registration action outside normal portfolio analysis. If abused or implemented loosely, it could silently add or modify MCP servers across agents, creating durable access paths and expanding the trusted tool surface without sufficiently informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Secret/API key parsing, env-var resolution, permission checks, and reverse secret mapping are highly sensitive capabilities. Reverse lookup or export-oriented handling of raw secrets increases the chance of accidental disclosure, misuse by agents, or crossing trust boundaries that users did not expect from an analytics skill.

External Script Fetching

High
Category
Supply Chain
Content
```bash
# What's configured?
curl -sS -X POST http://127.0.0.1:18090/api/portfolio/keys_status \
  -H 'Content-Type: application/json' -d '{}'
# → {"configured":["FINNHUB_KEY","NEWSAPI_KEY"], "settable":[...], "missing":[...]}
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Ae1

High
Category
analysis-evasion
Content
- Distribution-edge artifacts (this `SKILL.md`, `compose.yml`, `install.yaml`, `agent-skills/**`): **MIT-0** (MIT No Attribution — `LICENSE-MIT-0`). Required fo
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

MCP Config Access

High
Category
Agent Snooping
Content
## Step 5 — Fully quit and relaunch Claude Desktop

This step is critical. Closing the Claude Desktop window does **not**
reload the MCP config — the app keeps running in the background and
caches the old config.

- **macOS:** right-click the Claude Desktop icon in the Dock and choose
Confidence
90% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Hidden Instructions

High
Category
Prompt Injection
Content
<!--
SPDX-License-Identifier: MIT-0
Copyright 2026 InvestorClaw Contributors
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Static analysis

No suspicious patterns detected.