07. Security and Safety¶
Threat model (product intent)¶
Browser RAG aims for document privacy: user files, chunks, and chat history stay in browser storage. It does not claim zero network use — embedding and LLM weights download from external CDNs.
Authentication and authorization¶
None. Single-user, same-origin browser storage. Anyone with device access can read IndexedDB/localStorage for the origin.
Tenant / workspace isolation¶
Projects isolate documents and history by project_id. This is application-level partitioning inside one browser profile, not multi-tenant server isolation.
Sandbox and tool safety¶
- No remote code execution sandbox
- Tool calling disabled (
toolsEnabled: false, tool round caps at 0) - PDF extraction uses
@llamaindex/liteparse-wasmwith OCR off; sparse PDFs setocrRequiredmetadata only
Input validation and file handling¶
| Control | Evidence |
|---|---|
| Local file pick / upload | Documents route |
| MIME/extension branching | src/rag/extractors/index.ts |
| Backup extension checks | Settings import UI |
| Original bytes in IDB | document-files.ts for retry |
No virus scanning or server-side content policy (N/A for client-only).
Secret management¶
No app secrets. Avoid pasting API keys into chat if a future remote engine were added — EmbeddingModelConfig.engine includes 'remote' but no remote provider is implemented.
Model / tool safety boundaries¶
- Answer prompt instructs “use only the context provided”
- Empty retrieval short-circuits generation
- Thinking streams are UI-only; tools not executed
- XSS surface: assistant/history HTML via
marked.parse+dangerouslySetInnerHTML(src/routes/index.tsx,history.tsx) — malicious document content that reaches the answer could become HTML
Audit logging¶
query_history stores queries, answers, and retrieved chunk JSON locally. No remote audit trail.
Known gaps and hardening opportunities¶
| Risk | Severity | Notes |
|---|---|---|
Markdown XSS via dangerouslySetInnerHTML |
Medium | Sanitize or use a safe renderer |
| Model weight egress | Low–Info | Expected; document content should not leave |
| Production COOP/COEP unknown | Medium | May weaken WASM threading / isolation on Pages |
| Soft embedding model lock | Medium | Changing model without re-index can break retrieval quality |
| Backup omits file IDB | Low | Retry bytes lost after restore |
| No auth on shared machines | Context-dependent | Clear data / separate profiles |
Security interview questions¶
Q: Does any document text leave the machine?
A: Application code does not POST documents to an API. Weights download from CDNs. Users should still treat browser extensions and device compromise as out-of-scope threats.
Q: What’s the biggest web security footgun?
A: Rendering model output as HTML without sanitization.
Q: How do you get SharedArrayBuffer?
A: Cross-origin isolation via COOP/COEP — configured for Vite dev/preview; production hosting must also send those headers.