mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-08-05 19:05:28 +00:00
The email auto-calendar pass (settings.email_auto_calendar / the extract_email_events task) scans recently received mail and lets an LLM create / update / cancel calendar events. Two problems made it a cross-tenant, remotely triggerable hole: 1. No owner scoping. _auto_summarize_pass(account_id=None) fans out over EVERY enabled account of EVERY user. For each message it fetched an upcoming-events snapshot with NO owner filter (all tenants' events) and handed those uids + titles to the extraction LLM, then executed the model's ops via do_manage_calendar(...) with owner=None. do_manage_calendar only filters by owner when owner is not None, so create/update/delete ran across ALL users' calendars. Net: every user's event titles/times were disclosed to the model, and the model could cancel/move/duplicate any tenant's events by uid. 2. No prompt-injection wrapping. The raw email From/Subject/body were interpolated straight into an instruction-shaped extraction prompt (unlike the chat path, which wraps external text via src/prompt_security). Anyone who can email a user whose instance has auto-calendar enabled could inject operations: create attacker-controlled "meeting" events (the path even auto-harvests URLs from the body into the event location/description — a phishing primitive) or cancel/modify the victim's real events, with zero human in the loop. Fix: - Add core.database.get_upcoming_events(owner) and use it for the snapshot, so the LLM only ever sees the processed account owner's events. - Look up the EmailAccount owner in _auto_summarize_pass_single and pass owner= to every do_manage_calendar call, so create/update/delete are scoped to that user (owner=None stays the single-user / legacy escape hatch). - Tell the extraction model the email is untrusted data and not to follow instructions inside it (defense-in-depth against injection). Add tests/test_calendar_owner_scope.py: get_upcoming_events returns only the given owner's events (and everything when owner is None). Fails against the old unscoped query. |
||
|---|---|---|
| .. | ||
| bombadil-spec.ts | ||
| conftest.py | ||
| test_action_intents.py | ||
| test_agent_loop.py | ||
| test_app.py | ||
| test_auth_event_loop.py | ||
| test_auth_regressions.py | ||
| test_calendar_owner_scope.py | ||
| test_calendar_recurrence.py | ||
| test_chat_stream_scope.py | ||
| test_chroma_client.py | ||
| test_compare_js.py | ||
| test_context_compactor.py | ||
| test_cookbook_helpers.py | ||
| test_deep_research_extraction_controls.py | ||
| test_endpoint_resolver.py | ||
| test_gallery_image_privileges.py | ||
| test_hwfit_macos.py | ||
| test_llm_core_ollama.py | ||
| test_model_context.py | ||
| test_model_routes.py | ||
| test_null_owner_gates.py | ||
| test_pdf_runtime.py | ||
| test_personal_docs_pdf_index.py | ||
| test_personal_upload_isolation.py | ||
| test_rate_limiter.py | ||
| test_reply_recipients_js.py | ||
| test_research_utils.py | ||
| test_review_regressions.py | ||
| test_search_query.py | ||
| test_search_ranking.py | ||
| test_security_regressions.py | ||
| test_session_mode_helpers.py | ||
| test_settings_scrub.py | ||
| test_setup_admin_user.py | ||
| test_shell_routes.py | ||
| test_task_scheduler_session_delivery.py | ||
| test_vision_model_detection.py | ||
| test_visual_report.py | ||