mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-31 21:07:23 +02:00
* refactor: better SSRF Protection in Action and Tool Services - Added `createSSRFSafeAgents` function to create HTTP/HTTPS agents that block connections to private/reserved IP addresses, enhancing security against SSRF attacks. - Updated `createActionTool` to accept a `useSSRFProtection` parameter, allowing the use of SSRF-safe agents during tool execution. - Modified `processRequiredActions` and `loadAgentTools` to utilize the new SSRF protection feature based on allowed domains configuration. - Introduced `resolveHostnameSSRF` function to validate resolved IPs against private ranges, preventing potential SSRF vulnerabilities. - Enhanced tests for domain resolution and private IP detection to ensure robust SSRF protection mechanisms are in place. * feat: Implement SSRF protection in MCP connections - Added `createSSRFSafeUndiciConnect` function to provide SSRF-safe DNS lookup options for undici agents. - Updated `MCPConnection`, `MCPConnectionFactory`, and `ConnectionsRepository` to include `useSSRFProtection` parameter, enabling SSRF protection based on server configuration. - Enhanced `MCPManager` and `UserConnectionManager` to utilize SSRF protection when establishing connections. - Updated tests to validate the integration of SSRF protection across various components, ensuring robust security measures are in place. * refactor: WS MCPConnection with SSRF protection and async transport construction - Added `resolveHostnameSSRF` to validate WebSocket hostnames against private IP addresses, enhancing SSRF protection. - Updated `constructTransport` method to be asynchronous, ensuring proper handling of SSRF checks before establishing connections. - Improved error handling for WebSocket transport to prevent connections to potentially unsafe addresses. * test: Enhance ActionRequest tests for SSRF-safe agent passthrough - Added tests to verify that httpAgent and httpsAgent are correctly passed to axios.create when provided in ActionRequest. - Included scenarios to ensure agents are not included when no options are specified. - Enhanced coverage for POST requests to confirm agent passthrough functionality. - Improved overall test robustness for SSRF protection in ActionRequest execution.
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import dns from 'node:dns';
|
|
import http from 'node:http';
|
|
import https from 'node:https';
|
|
import type { LookupFunction } from 'node:net';
|
|
import { isPrivateIP } from './domain';
|
|
|
|
/** DNS lookup wrapper that blocks resolution to private/reserved IP addresses */
|
|
const ssrfSafeLookup: LookupFunction = (hostname, options, callback) => {
|
|
dns.lookup(hostname, options, (err, address, family) => {
|
|
if (err) {
|
|
callback(err, '', 0);
|
|
return;
|
|
}
|
|
if (typeof address === 'string' && isPrivateIP(address)) {
|
|
const ssrfError = Object.assign(
|
|
new Error(`SSRF protection: ${hostname} resolved to blocked address ${address}`),
|
|
{ code: 'ESSRF' },
|
|
) as NodeJS.ErrnoException;
|
|
callback(ssrfError, address, family as number);
|
|
return;
|
|
}
|
|
callback(null, address as string, family as number);
|
|
});
|
|
};
|
|
|
|
/** Internal agent shape exposing createConnection (exists at runtime but not in TS types) */
|
|
type AgentInternal = {
|
|
createConnection: (options: Record<string, unknown>, oncreate?: unknown) => unknown;
|
|
};
|
|
|
|
/** Patches an agent instance to inject SSRF-safe DNS lookup at connect time */
|
|
function withSSRFProtection<T extends http.Agent>(agent: T): T {
|
|
const internal = agent as unknown as AgentInternal;
|
|
const origCreate = internal.createConnection.bind(agent);
|
|
internal.createConnection = (options: Record<string, unknown>, oncreate?: unknown) => {
|
|
options.lookup = ssrfSafeLookup;
|
|
return origCreate(options, oncreate);
|
|
};
|
|
return agent;
|
|
}
|
|
|
|
/**
|
|
* Creates HTTP and HTTPS agents that block TCP connections to private/reserved IP addresses.
|
|
* Provides TOCTOU-safe SSRF protection by validating the resolved IP at connect time,
|
|
* preventing DNS rebinding attacks where a hostname resolves to a public IP during
|
|
* pre-validation but to a private IP when the actual connection is made.
|
|
*/
|
|
export function createSSRFSafeAgents(): { httpAgent: http.Agent; httpsAgent: https.Agent } {
|
|
return {
|
|
httpAgent: withSSRFProtection(new http.Agent()),
|
|
httpsAgent: withSSRFProtection(new https.Agent()),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns undici-compatible `connect` options with SSRF-safe DNS lookup.
|
|
* Pass the result as the `connect` property when constructing an undici `Agent`.
|
|
*/
|
|
export function createSSRFSafeUndiciConnect(): { lookup: LookupFunction } {
|
|
return { lookup: ssrfSafeLookup };
|
|
}
|