Security at K25x
We treat your financial data the way we'd want our own treated. That means concrete defaults — not just policies.
How your data is protected
Your data stays on your device
Transactions, balances, and goals live in your browser. Cloud sync is optional — you turn it on if you want to use K25x on more than one device.
Strong encryption for anything sensitive
Your two-factor secret and the AI advisor’s learned facts about you are AES-GCM encrypted before they touch your browser storage. The encryption key is non-extractable: a malicious browser extension cannot copy the key itself, though an extension running in the page could still use it while the app is unlocked — which is why extensions stay in our threat model below. When bank connections launch (planned Q1 2027), any access tokens will be stored on our servers (Google Cloud Firestore, encrypted at rest) and access-controlled to your account — never kept in your browser.
Two-factor authentication, when you want it
Turn on an authenticator-app code for sign-in anytime from Settings — it's optional but strongly recommended. Works with 1Password, Authy, Google Authenticator, Bitwarden — whichever you already use. You'll get recovery codes when you set it up; keep them somewhere safe.
Optional password to lock the app
Add a master password and the app re-prompts for it whenever you've been idle for 30 minutes. The password never leaves your device — we use it locally to unlock the encryption key.
AI input is sanitized before it reaches the model
Anything you type into the AI advisor is sent to our server, where it is cleaned of common tricks attackers use to manipulate language models before being forwarded to the AI provider. Local mode (Settings → AI Privacy) routes AI calls through our server to a self-hosted model (Ollama) instead of Google or Anthropic — your data still transits our server and goes to whichever model host the server is configured to use. When you turn on on-device AI (on a WebGPU browser such as Chrome or Edge on desktop), the model itself runs in your browser and reads your saved financial data — balances, holdings, accounts — locally; what leaves your device is the question you type, plus your jurisdiction and currency settings, which go to our server for a required safety check. Because your typed question does travel, avoid putting specific balances or account numbers in it.
Threat model — what we defend against
| Threat | Defense |
|---|---|
| XSS via user-supplied transaction text | Strict CSP with nonce + strict-dynamic; sanitize-on-render |
| Prompt injection via emails/SMS/PDFs | ai-sanitize.ts neutralizes injection markers; magic-byte checks on uploads |
| Filesystem read of browser profile | Optional PBKDF2 password vault — without password, encrypted credentials unrecoverable |
| Token-budget exhaustion / abuse | Per-user monthly envelope, file-size limits on AI uploads |
| Cookie tampering for local-only bypass | Middleware blocks /api/plaid, /api/lean, /api/email-parse, /api/expat when cookie set |
| Cross-tab DEK exposure | Per-tab in-memory; auto-locks after 30 min of inactivity |
| Sentry/PostHog leaking PII | Both scrub email + numeric clusters; both honor disable-analytics flag |
| LocalStorage corruption silent reset | loadValidated() quarantines bad data + surfaces a recovery toast |
Responsible disclosure
Found a security issue? Don't open a public GitHub issue. Email security@k25x.ai and we'll respond within 72 hours under safe-harbor.
- Acknowledge: within 72 hours.
- Assess + scope: within 5 business days.
- Fix or mitigate: within 30 days for high-severity issues; 90 days for medium; lower-severity items roll into the next release.
- Credit: we credit reporters in our changelog unless you prefer anonymity.
We don't currently run a paid bug bounty, but we do maintain a public hall of fame for verified reports.