LibreChat/packages/api
Danny Avila 4fd09946d2
🔒 fix: Better SSRF protection for Actions (#11143)
Addresses Server-Side Request Forgery vulnerability that allowed authenticated
attackers to interact with arbitrary internal/external HTTP services via the
Actions feature, including the internal RAG API, localhost services, and cloud
metadata endpoints.

## Security Changes

### 1. SSRF Target Blocklist (when allowedDomains is empty)
- Block localhost and loopback addresses (127.0.0.0/8, ::1)
- Block private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
- Block link-local/cloud metadata IPs (169.254.0.0/16)
- Block common internal Docker/Kubernetes service names (rag_api, redis, mongo, etc.)
- Block .internal and .local TLDs

Admins can still explicitly allow internal targets by adding them to
`actions.allowedDomains` in librechat.yaml.

### 2. Protocol and Port Restrictions
Enhanced `allowedDomains` to support protocol and port constraints:
- `example.com` - any protocol, any port (existing behavior)
- `https://example.com` - HTTPS only, any port
- `https://api.example.com:8443` - HTTPS only, port 8443 only

This allows admins to restrict actions to specific protocols/ports, preventing
attackers from accessing unintended services on allowed domains.

### 3. Redirect-based SSRF Prevention
Disabled automatic redirect following in action HTTP requests (`maxRedirects: 0`).
This prevents attackers from bypassing domain restrictions by:
1. Pointing action to allowed external domain
2. External domain redirects to internal service (e.g., 127.0.0.1)
3. Server follows redirect and accesses internal service

## Files Changed
- packages/api/src/auth/domain.ts: Added isSSRFTarget(), parseDomainSpec(),
  updated isActionDomainAllowed() with protocol/port matching
- packages/api/src/auth/domain.spec.ts: Added tests for SSRF protection,
  protocol restrictions, and port restrictions
- packages/data-provider/src/actions.ts: Added maxRedirects: 0 to axios config

## Configuration Example
# librechat.yaml
actions:
  allowedDomains:
    - "https://api.example.com"        # HTTPS only
    - "https://api.example.com:8443"   # HTTPS + specific port
    - "http://localhost:3000"          # Admin override for local devRef: SBA-ADV-20251205-02
CVSSv3: 9.1 (Critical) - CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L
2025-12-29 15:09:55 -05:00
..
src 🔒 fix: Better SSRF protection for Actions (#11143) 2025-12-29 15:09:55 -05:00
.gitignore 🧠 feat: User Memories for Conversational Context (#7760) 2025-06-07 18:52:22 -04:00
babel.config.cjs 🧠 feat: User Memories for Conversational Context (#7760) 2025-06-07 18:52:22 -04:00
jest.config.mjs 🔄 refactor: MCP Registry System with Distributed Caching (#10191) 2025-10-31 15:00:21 -04:00
package.json 📦 chore: bump MCP SDK to v1.25.1 and fix packages/api ghost dependencies (#11128) 2025-12-28 11:49:41 -05:00
rollup.config.js 🔄 refactor: Migrate Cache Logic to TypeScript (#9771) 2025-10-02 09:33:58 -04:00
tsconfig-paths-bootstrap.mjs 🧠 feat: User Memories for Conversational Context (#7760) 2025-06-07 18:52:22 -04:00
tsconfig.build.json 🧑‍💻 refactor: Secure Field Selection for 2FA & API Build Sourcemap (#9087) 2025-08-15 18:55:49 -04:00
tsconfig.json 🌊 feat: Resumable LLM Streams with Horizontal Scaling (#10926) 2025-12-19 12:14:19 -05:00
tsconfig.spec.json 🧠 feat: User Memories for Conversational Context (#7760) 2025-06-07 18:52:22 -04:00