Skip to content

Security: mshafir/investbot

Security

SECURITY.md

Security

This tool holds OAuth credentials for a brokerage account and can place orders against it. Treat every part of it accordingly.

What is sensitive

thing where protection
Schwab app key and secret .env gitignored; never logged
Your contact address for EDGAR .env gitignored; sent only to sec.gov in the User-Agent
OAuth token ~/.investbot/token.json gitignored pattern *token*.json; 7-day expiry
Account numbers and hashes API responses redacted to last-four at every output boundary
Your holdings and targets portfolio.toml gitignored; committed example only
Your trading allowlist and limits risk.toml gitignored; committed example only
Orders you intend to place orders.toml gitignored; committed example only
Tax lots and cost basis data/ledger.db gitignored
Every placement and refusal ~/.investbot/audit.jsonl outside the repo; contains order ids, not account numbers

Reporting

If you find a way to make this tool place an order it should not, leak an account identifier, or reach /orders from a path other than investbot place --live, please report it privately rather than in a public issue. Open a GitHub security advisory on this repository, or contact the maintainer directly.

Include what you did, what happened, and what you expected. A failing test that demonstrates it is the best possible report.

What we consider a vulnerability

  • Any path to /orders that does not pass through execute_orders with both execution_enabled and live=True.
  • Any way for the MCP server to arm execution.
  • Any retry around post_once. Schwab has no idempotency key; a retry is a double-execution.
  • A full account number or hash reaching stdout, a log line, an MCP response, or an exception message.
  • A committed file containing real holdings, balances, lots, or orders.
  • A test in the default suite that reaches the network.

What we do not consider a vulnerability

  • The 7-day token expiry. It is Schwab's policy and the reason this tool cannot run unattended.
  • The absence of paper trading. Also Schwab's.
  • That a user with a correctly configured risk.toml and a deliberately written orders.toml can lose money. The tool bounds the blast radius of a mistake; it does not evaluate the trade.

Dependencies

schwab-py handles OAuth. httpx handles everything else. yfinance scrapes Yahoo and is used for backtests and fund metadata only -- it is never in the trading path. Keep them current; run the contract tests after a bump.

There aren't any published security advisories