Commit graph

2 commits

Author SHA1 Message Date
Danny Avila
f8774983a0
🪪 fix: Misleading MCP Server Lookup Method Name (#11315)
* 🔧 fix: MCP server ID resolver in access permissions (#11315)

- Replaced `findMCPServerById` with `findMCPServerByObjectId` in access permissions route and corresponding tests for improved clarity and consistency in resource identification.

* 🔧 refactor: Update MCP server resource access methods to use server name

- Replaced instances of `findMCPServerById` with `findMCPServerByServerName` across middleware, database, and test files for improved clarity and consistency in resource identification.
- Updated related comments and test cases to reflect the change in method usage.

* chore: Increase timeout for Redis update in GenerationJobManager integration tests

- Updated the timeout duration from 50ms to 200ms in the GenerationJobManager integration tests to ensure reliable verification of final event data in Redis after emitting the done event.
2026-01-12 21:04:25 -05:00
Danny Avila
06ba025bd9
🔒 fix: Access Control on Agent Permission Queries (#11145)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Adds access control check to GET /api/permissions/:resourceType/:resourceId
endpoint to prevent unauthorized disclosure of agent permission information.

## Vulnerability Summary

LibreChat version 0.8.1-rc2 did not enforce proper access control when
querying agent permissions. Any authenticated user could read the permissions
of arbitrary agents by knowing the agent ID, even for private agents they
had no access to.

**Impact:**
- Attackers could enumerate which users have access to private agents
- Permission levels (owner, editor, viewer) were exposed
- User emails and names of permitted users were disclosed
- Agent's public/private sharing status was revealed

**Attack Vector:**
```
GET /api/permissions/agent/{agent_id}
Authorization: Bearer <any_valid_token>
```

The MongoDB ObjectId format (timestamp + process ID + counter) made it
feasible to brute-force discover valid agent IDs.

## Fix

Added `checkResourcePermissionAccess` middleware factory that enforces
SHARE permission before allowing access to permission queries. This
middleware is now applied to the GET endpoint, matching the existing
access control on the PUT endpoint.

**Before:**
```javascript
router.get('/:resourceType/:resourceId', getResourcePermissions);
```

**After:**
```javascript
router.get(
  '/:resourceType/:resourceId',
  checkResourcePermissionAccess(PermissionBits.SHARE),
  getResourcePermissions,
);
```

The middleware handles all supported resource types:
- Agent (ResourceType.AGENT)
- Prompt Group (ResourceType.PROMPTGROUP)
- MCP Server (ResourceType.MCPSERVER)

## Code Changes

**api/server/routes/accessPermissions.js:**
- Added `checkResourcePermissionAccess()` middleware factory
- Applied middleware to GET /:resourceType/:resourceId endpoint
- Refactored PUT endpoint to use the same middleware factory (DRY)

**api/server/routes/accessPermissions.test.js:**
- Added security tests verifying unauthorized access is denied
- Tests confirm 403 Forbidden for users without SHARE permission

## Security Tests

```
✓ should deny permission query for user without access (main vulnerability test)
✓ should return 400 for unsupported resource type
✓ should deny permission update for user without access
2025-12-29 15:10:31 -05:00