Back to skill

Security audit

openInvest

Security checks for vulnerabilities and agentic risk

Overview

Review is needed because the documented workflow for saving AI analysis can execute commands embedded in that analysis.

Use the documented MCP submit_committee tool instead of the shell heredoc workflow until corrected. Confirm which provider or remote hub receives your portfolio information, including during import previews. Keep live brokerage trading disabled unless you deliberately configure and authorize it, and enter credentials locally rather than in chat.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
.
Finding

Unquoted heredocs interpret committee transcript text as shell commands

Content
View full analysis

Impact

Successful exploitation permits arbitrary commands under the calling account, including access to locally readable investment configuration and credentials or modification of local files.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (22)

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 · README.md (reported line 44)May include surrounding context.

bash
cd $INVEST_HOME
# 1. Edit SKILL.md / scripts/run.sh / references/*.md
vim skills/invest/SKILL.md
# 2. Test (the symlink is already live; no reinstall needed)
<skill-dir>/scripts/run.sh status

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

Although the initialized data is relevant to investment management, this chunk performs onboarding rather than the declared daily-use workflow. The explicit separation of first-time setup makes this a scope mismatch, not merely an unspecified implementation detail. The snippet does not show external data transmission or trade execution.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

text
1. Run `run.sh doctor` (no shell access? call the MCP `doctor` tool — same output)   ← mandatory first step
   ├─ status: "ready"        → go to step 2 (keep using this skill). A missing LLM key / mail
   │                          credentials / .env shows up only as `optional_*` checks and never
   │                          flips the status: Coordinator needs no key (only Direct does — see
   │                          `direct_ready`), so do NOT re-onboard for those
   └─ status: "needs_setup"  → memory not initialized (or portfolio.md still the v1 format) →

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 260)May include surrounding context.

md
| Command | Remote-mode behavior |
|------|--------------|
| `doctor` | Returns **hub-perspective** checks + an extra `remote` section (api_base / auth mode / connectivity) |
| `init` | **Disabled** (data lives on the hub; connecting to the hub only needs the two .env lines above). Error includes a hint |
| `live_prices` / `correlate` | Still run **locally** (pure yfinance, touches no data) |
| `run_committee` | Runs on the **hub** (DeepSeek key is on the hub); the CLI polls automatically until done; same-day cache uses the hub's date semantics |
| `prepare/save_committee` | Via hub RPC — the Coordinator protocol (spawn 4 subagents) is **completely unchanged** |

The tool catalog exposes autonomous real-money brokerage trading beyond the stated portfolio-management and investment-verdict workflow.

High
Category
Excessive Agency
Confidence
90% confidence
Finding

The documented ibkr_autopilot capability lets an LLM select securities, generate orders, and submit real Interactive Brokers trades, using committee verdicts only as reference input. This goes beyond recording position adjustments or producing investment recommendations; requiring operator use and explicit enablement limits exposure but does not justify autonomous brokerage execution within the stated skill purpose.

Content

No source excerpt is available for this finding.

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 · references/tools.md (reported line 111)May include surrounding context.

md
| `POST /api/events/check` | Manually run event_watch once (fetch news + normalize + store + trigger the committee on hits). Synchronous, 30-90s | — |
| `GET /api/config` | View the current effective values of the API-configurable whitelist parameters (+ whether overridden + metadata) | — |
| `PUT /api/config` | Set one whitelist override (persisted to disk, shared across processes, takes precedence over env; ADR-017) | `{key, value}`, e.g. `{"key":"verdict.concentration_lens_enabled","value":false}` |
| `DELETE /api/config/{key}` | Delete an override, reverting to the default | — |

**Typical flow**: the user says "I plan to..." (我打算...) / "just bought X" (刚买了 X) / "my
position in Y grew" (我的持仓多了 Y) → use `POST /api/trades/record` (with intended_date to

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/run.sh (reported line 7)May include surrounding context.

sh
# 2026-07 起后端从 PyPI 分发(pypi.org/project/openinvest),本脚本不再
# git clone / uv sync / 自愈更新——那 180 行 bash 全部退役:
#   - 后端代码:uvx 按需拉 openinvest 包(缓存于 uv cache,首跑需网络)
#   - 数据目录:$INVEST_HOME(默认 ~/openInvest),只放 memory/ db/ .env static/
#   - 更新:后端版本固定在下方 SPEC,随插件发版更新;`run.sh update`(= uvx --refresh)只重下这个固定版本,用于修坏掉的缓存
#   - GUI dist 拉取 / 远端模式提示等业务逻辑收进 openinvest-web(Python)
#

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 45)May include surrounding context.

bash
cd $INVEST_HOME
# 1. Edit SKILL.md / scripts/run.sh / references/*.md
vim skills/invest/SKILL.md
# 2. Test (the symlink is already live; no reinstall needed)
<skill-dir>/scripts/run.sh status
# 3. commit + push

MCP server referenced without pinned version: 'uvx openinvest'.

Medium
Category
MCP Rug Pull
Confidence
65% confidence
Finding

uvx/uv tool run commands without ==version create a rug-pull risk.

Content

No source excerpt is available for this finding.

MCP server referenced without pinned version: 'uvx openinvest'.

Medium
Category
MCP Rug Pull
Confidence
65% confidence
Finding

uvx/uv tool run commands without ==version create a rug-pull risk.

Content

No source excerpt is available for this finding.

The Direct workflow lacks a privacy warning that investment context is sent to the configured external LLM provider.

Medium
Category
Output Handling
Confidence
90% confidence
Finding

The Direct workflow sends investment-analysis context to a configured external model, but the document does not clearly explain which portfolio or strategy details leave the user's environment or require informed approval for that disclosure. External model use is openly described, which reduces suspicion of covert exfiltration, but sensitive financial context still warrants an explicit privacy boundary.

Content

No source excerpt is available for this finding.

Behavior Manipulation

Medium
Category
Prompt Injection
Confidence
75% confidence
Finding

Subtle instructions detected that may alter agent decision-making or introduce hidden biases.

Content

Scanner excerpt · SKILL.md (reported line 399)May include surrounding context.

md
**always** portfolio cash — this never changes
- **`max_single_invest_cny` ("单次上限") is a per-order cap on the suggested amount — not a daily or
  total allowance, and orders can be split.** When the memo says "金额已按单次上限 … 钳制", the CIO's
  amount was cut to that cap per order. Never tell the user "today's allowance is used up" because of it
- **Dividends / interest / fees / taxes / splits are ledger activities, not trades or deposits**: `record_dividend`
  (cash + gross − tax withheld; `--reinvest` = DRIP), `record_fee` (`--kind tax` for tax), `record_split`
  (`--ratio` = new/old: 10-for-1 → 10, 1-for-10 → 0.1; pass the real ex-date — if later trades were already booked in post-split units it is refused, and `--ledger-only` writes the ledger row without touching units),

The daily-use skill performs first-time onboarding instead of handing off to invest-setup as its manifest requires.

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

The manifest explicitly assigns first-time installation to the separate invest-setup skill and requires switching to it when doctor returns needs_setup. This file targets that exact condition but instead instructs both agent paths to collect setup answers and execute run.sh init --from-stdin, crossing the stated boundary between daily operations and installation.

Content

No source excerpt is available for this finding.

The onboarding workflow sends financial holdings to an external LLM without requiring a user-facing privacy disclosure.

Medium
Category
Output Handling
Confidence
96% confidence
Finding

The workflow automatically sends the user's holdings description to an external LLM when a key is available, without requiring disclosure and consent for that specific transfer. Holdings descriptions can contain sensitive asset, cash-balance, and financial-institution information; mentioning DeepSeek in the documentation or having an existing API key does not establish informed permission to share this data.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/onboarding.md (reported line 109)May include surrounding context.

md
## Q4 details: keys go in `.env`, never in the chat

**Never ask the user to paste an API key or password into the chat, and never put one into a
command you run** — it would land in the transcript and in the model provider's logs. Tell the user
to add the lines they need to `$INVEST_HOME/.env` (default `~/openInvest/.env`; `run.sh doctor`
prints the data directory) with their own editor, or to run `run.sh init` in their own terminal,

The screenshot-import workflow sends sensitive holdings data to a backend LLM without a user-facing privacy warning.

Medium
Category
Output Handling
Confidence
93% confidence
Finding

The screenshot workflow instructs the agent to transcribe sensitive portfolio details and submit them to an LLM-backed import endpoint without first explaining the model-processing destination or obtaining informed consent. Preview mode prevents ledger writes, not LLM processing, so a user may disclose holdings to a configured external provider before approving the import; the actual exposure depends on the deployment's model configuration.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
60% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/run.sh (reported line 67)May include surrounding context.

sh
;;
  update)
    if [ "$DEV_MODE" = "1" ]; then
      echo "⬆️  OPENINVEST_DEV_MODE=1:本地源码模式不走 PyPI refresh;请改完代码后运行 uv sync。" >&2
      cd "$REPO_ROOT"
      export PYTHONPATH="$SRC_ROOT${PYTHONPATH:+:$PYTHONPATH}"
      exec uv run python -m openinvest.cli doctor

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
60% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/run.sh (reported line 97)May include surrounding context.

sh
update   更新后端到 PyPI 最新版

开发:
  export OPENINVEST_DEV_MODE=1
          走本地源码 `uv run python -m openinvest.cli ...`,用于验证未发布的改动

完整子命令表:uvx openinvest --help 或 skills/invest/references/tools.md

MCP server referenced without pinned version: 'uvx openinvest'.

Medium
Category
MCP Rug Pull
Confidence
65% confidence
Finding

uvx/uv tool run commands without ==version create a rug-pull risk.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
60% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/run.sh (reported line 108)May include surrounding context.

sh
if [ "$DEV_MODE" = "1" ]; then
      cd "$REPO_ROOT"
      export PYTHONPATH="$SRC_ROOT${PYTHONPATH:+:$PYTHONPATH}"
      run_with_hint "本地源码模式(OPENINVEST_DEV_MODE=1)没输出任何结果就退出了,原因见 stderr 的报错。常见:依赖没装(先运行 uv sync)。" \
          uv run python -m openinvest.cli "$@"
      exit $?
    fi

The trigger "analyze X" is not limited to investment-related requests.

Low
Category
Trigger Abuse
Confidence
94% confidence
Finding

"Analyze X" can apply to documents, code, or many other non-investment subjects. Although the surrounding README describes an investment skill, this trigger does not explicitly restrict X to financial assets or exclude unrelated analysis requests.

Content

No source excerpt is available for this finding.

MCP server dependency without pinned version: 'pip install openbb-mcp-server'.

Low
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The optional OpenBB integration explicitly recommends installing both openbb-mcp-server and openbb without version constraints or integrity verification. This permits newly published or compromised releases to execute in the user's environment, potentially exposing portfolio data and credentials; keeping the server on localhost does not mitigate installation-time compromise.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.