LibreChat/api/server/middleware/accessResources
Danny Avila 8dc6d60750
🛡️ fix: Enforce MULTI_CONVO and agent ACL checks on addedConvo (#12243)
* 🛡️ fix: Enforce MULTI_CONVO and agent ACL checks on addedConvo

addedConvo.agent_id was passed through to loadAddedAgent without any
permission check, enabling an authenticated user to load and execute
another user's private agent via the parallel multi-convo feature.

The middleware now chains a checkAddedConvoAccess gate after the primary
agent check: when req.body.addedConvo is present it verifies the user
has MULTI_CONVO:USE role permission, and when the addedConvo agent_id is
a real (non-ephemeral) agent it runs the same canAccessResource ACL
check used for the primary agent.

* refactor: Harden addedConvo middleware and avoid duplicate agent fetch

- Convert checkAddedConvoAccess to curried factory matching Express
  middleware signature: (requiredPermission) => (req, res, next)
- Call checkPermission directly for the addedConvo agent instead of
  routing through canAccessResource's tempReq pattern; this avoids
  orphaning the resolved agent document and enables caching it on
  req.resolvedAddedAgent for downstream loadAddedAgent
- Update loadAddedAgent to use req.resolvedAddedAgent when available,
  eliminating a duplicate getAgent DB call per chat request
- Validate addedConvo is a plain object and agent_id is a string
  before passing to isEphemeralAgentId (prevents TypeError on object
  injection, returns 400-equivalent early exit instead of 500)
- Fix JSDoc: "VIEW access" → "same permission as primary agent",
  add @param/@returns to helpers, restore @example on factory
- Fix redundant return await in resolveAgentIdFromBody

* test: Add canAccessAgentFromBody spec covering IDOR fix

26 integration tests using MongoMemoryServer with real models, ACL
entries, and PermissionService — no mocks for core logic.

Covered paths:
- Factory validation (requiredPermission type check)
- Primary agent: missing agent_id, ephemeral, non-agents endpoint
- addedConvo absent / invalid shape (string, array, object injection)
- MULTI_CONVO:USE gate: denied, missing role, ADMIN bypass
- Agent resource ACL: no ACL → 403, insufficient bits → 403,
  nonexistent agent → 404, valid ACL → next + cached on req
- End-to-end: both real agents, primary denied short-circuits,
  ephemeral primary + real addedConvo
2026-03-15 17:12:45 -04:00
..
canAccessAgentFromBody.js 🛡️ fix: Enforce MULTI_CONVO and agent ACL checks on addedConvo (#12243) 2026-03-15 17:12:45 -04:00
canAccessAgentFromBody.spec.js 🛡️ fix: Enforce MULTI_CONVO and agent ACL checks on addedConvo (#12243) 2026-03-15 17:12:45 -04:00
canAccessAgentResource.js 🔧 refactor: Organize Sharing/Agent Components and Improve Type Safety 2025-08-13 16:24:20 -04:00
canAccessAgentResource.spec.js 🔧 refactor: Permission handling for Resource Sharing (#11283) 2026-01-10 14:02:56 -05:00
canAccessMCPServerResource.js 🪪 fix: Misleading MCP Server Lookup Method Name (#11315) 2026-01-12 21:04:25 -05:00
canAccessMCPServerResource.spec.js 🪪 fix: Misleading MCP Server Lookup Method Name (#11315) 2026-01-12 21:04:25 -05:00
canAccessPromptGroupResource.js 🔧 refactor: Organize Sharing/Agent Components and Improve Type Safety 2025-08-13 16:24:20 -04:00
canAccessPromptViaGroup.js 🔧 refactor: Organize Sharing/Agent Components and Improve Type Safety 2025-08-13 16:24:20 -04:00
canAccessResource.js 🛂 feat: Role as Permission Principal Type 2025-08-13 16:24:23 -04:00
fileAccess.js 🧵 refactor: Migrate Endpoint Initialization to TypeScript (#10794) 2025-12-11 16:37:16 -05:00
fileAccess.spec.js 🔧 refactor: Permission handling for Resource Sharing (#11283) 2026-01-10 14:02:56 -05:00
index.js 🏗️ feat: Dynamic MCP Server Infrastructure with Access Control (#10787) 2025-12-11 16:38:37 -05:00