Security hardening suite: RCE, SSRF, owner-scope, path confinement #938

Closed
opened 2026-06-18 10:56:09 +02:00 by sleepy · 0 comments
Owner

Overview

Adopt upstream security hardening across multiple attack surfaces. These are active vulnerability fixes our fork lacks.

Upstream References

MCP RCE (Agent-Path Injection)

  • PR #4433: Allowlist manage_mcp "add" to close the agent-path RCE. The agent can no longer inject arbitrary MCP commands through tool calls.
  • Upstream commit: 93569b1 fix(security): allowlist manage_mcp "add" to close the agent-path RCE (#4433)
  • Local path: ../odysseus_upstream/src/tool_implementations.py — see _validate_mcp_command() and _mcp_allowed_commands()

Agent Loop Hardening

  • PR #1629: Wrap non-native tool results as untrusted data in the agent loop. Prevents prompt injection through tool outputs.
  • Upstream commit: 4e47774 harden(agent-loop): wrap non-native tool results as untrusted data (#1629)
  • Local path: ../odysseus_upstream/src/agent_loop.py

SSRF / Web Fetch Guardrails

  • PR #3955: Download budgets to web_fetch with truncation notice and hard ceiling.
  • PR #3964: Route public emitters through fire_and_forget for webhook SSRF resilience.
  • Upstream commits: 074a1e6, 2196869
  • Local paths: ../odysseus_upstream/src/endpoint_resolver.py, ../odysseus_upstream/tests/test_webhook_ssrf_resilience.py

Owner Scope Hardening

Multiple owner-scope fixes upstream:

  • 7b09491 — check-in calendar digest leaks every users events (missing owner scope) #1925
  • 422f23f — scope memory server by owner #4315
  • 260ce8b — enforce MCP owner boundaries #4335
  • facc50c — attribute bearer-token actions to token owner #4054
  • 0750486 — fail closed when unauthenticated request reaches owner-scoped routes #4062
  • f602819 — scope API-token model listing #4292
  • b58af42 — require chat scope for model inventory #4319

Path Confinement

  • 745c10e — confine gallery image path resolution #4352
  • 81e7074 — confine replacement image path #4285
  • facc50c — research handler path confinement

CardDAV Password Encryption

  • PR #1741: Encrypt CardDAV password at rest in settings.json.
  • PR #305: Restrict API-key encryption key file to 0o600.

Implementation Plan

  1. Audit our src/tool_security.py against upstream src/tool_security.py
  2. Port MCP command allowlisting
  3. Port agent loop untrusted-data wrapping
  4. Port web_fetch download budgets and truncation
  5. Port owner-scope checks across routes (notes, memory, email, models, calendar)
  6. Port path confinement for gallery, personal uploads, research
  7. Port CardDAV password encryption
  8. Add relevant tests from upstream (see ../odysseus_upstream/tests/test_manage_mcp_command_allowlist.py, test_tool_output_prompt_injection.py, test_owner_isolation*.py, etc.)

Priority

Critical — these are vulnerability fixes, not features.

## Overview Adopt upstream security hardening across multiple attack surfaces. These are active vulnerability fixes our fork lacks. ## Upstream References ### MCP RCE (Agent-Path Injection) - **PR #4433**: Allowlist `manage_mcp "add"` to close the agent-path RCE. The agent can no longer inject arbitrary MCP commands through tool calls. - **Upstream commit**: `93569b1 fix(security): allowlist manage_mcp "add" to close the agent-path RCE (#4433)` - **Local path**: `../odysseus_upstream/src/tool_implementations.py` — see `_validate_mcp_command()` and `_mcp_allowed_commands()` ### Agent Loop Hardening - **PR #1629**: Wrap non-native tool results as untrusted data in the agent loop. Prevents prompt injection through tool outputs. - **Upstream commit**: `4e47774 harden(agent-loop): wrap non-native tool results as untrusted data (#1629)` - **Local path**: `../odysseus_upstream/src/agent_loop.py` ### SSRF / Web Fetch Guardrails - **PR #3955**: Download budgets to `web_fetch` with truncation notice and hard ceiling. - **PR #3964**: Route public emitters through `fire_and_forget` for webhook SSRF resilience. - **Upstream commits**: `074a1e6`, `2196869` - **Local paths**: `../odysseus_upstream/src/endpoint_resolver.py`, `../odysseus_upstream/tests/test_webhook_ssrf_resilience.py` ### Owner Scope Hardening Multiple owner-scope fixes upstream: - `7b09491` — check-in calendar digest leaks every users events (missing owner scope) #1925 - `422f23f` — scope memory server by owner #4315 - `260ce8b` — enforce MCP owner boundaries #4335 - `facc50c` — attribute bearer-token actions to token owner #4054 - `0750486` — fail closed when unauthenticated request reaches owner-scoped routes #4062 - `f602819` — scope API-token model listing #4292 - `b58af42` — require chat scope for model inventory #4319 ### Path Confinement - `745c10e` — confine gallery image path resolution #4352 - `81e7074` — confine replacement image path #4285 - `facc50c` — research handler path confinement ### CardDAV Password Encryption - **PR #1741**: Encrypt CardDAV password at rest in settings.json. - **PR #305**: Restrict API-key encryption key file to 0o600. ## Implementation Plan 1. Audit our `src/tool_security.py` against upstream `src/tool_security.py` 2. Port MCP command allowlisting 3. Port agent loop untrusted-data wrapping 4. Port web_fetch download budgets and truncation 5. Port owner-scope checks across routes (notes, memory, email, models, calendar) 6. Port path confinement for gallery, personal uploads, research 7. Port CardDAV password encryption 8. Add relevant tests from upstream (see `../odysseus_upstream/tests/test_manage_mcp_command_allowlist.py`, `test_tool_output_prompt_injection.py`, `test_owner_isolation*.py`, etc.) ## Priority **Critical** — these are vulnerability fixes, not features.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sleepy/odysseus#938
No description provided.