fix(security): close SSRF guard bypasses in ssrfGuard.js (#3714)
Closes four SSRF guard bypasses reported in #3714: - Block alternate IPv6 encodings (hex format, NAT64, IPv4-compatible, IPv4-mapped) by parsing to 16-bit groups - Normalize trailing dots on hostnames to prevent FQDN bypasses - Add assertPublicUrlResolved() with DNS resolution to block wildcard DNS domains resolving to private/metadata IPs - Add fetchPublic() to safely handle and validate HTTP redirects
This commit is contained in:
@@ -13,7 +13,7 @@ import { HTTP_STATUS } from "open-sse/config/runtimeConfig.js";
|
||||
import * as log from "../utils/logger.js";
|
||||
import { updateProviderCredentials, checkAndRefreshToken } from "../services/tokenRefresh.js";
|
||||
import { handleComboChat, getComboModelsFromData } from "open-sse/services/combo.js";
|
||||
import { assertPublicUrl } from "@/shared/utils/ssrfGuard.js";
|
||||
import { assertPublicUrlResolved } from "@/shared/utils/ssrfGuard.js";
|
||||
|
||||
/**
|
||||
* Handle web fetch (URL extraction) request for the SSE/Next.js server.
|
||||
@@ -79,9 +79,10 @@ export async function handleFetch(request) {
|
||||
return errorResponse(HTTP_STATUS.BAD_REQUEST, "Invalid URL format");
|
||||
}
|
||||
|
||||
// SSRF guard: reject internal/private/metadata targets
|
||||
// SSRF guard: reject internal/private/metadata targets, including
|
||||
// hostnames that merely resolve to one (DNS lookup, not just literal checks).
|
||||
try {
|
||||
assertPublicUrl(targetUrl);
|
||||
await assertPublicUrlResolved(targetUrl);
|
||||
} catch (err) {
|
||||
log.warn("FETCH", "Blocked URL", { url: targetUrl });
|
||||
return errorResponse(HTTP_STATUS.BAD_REQUEST, err.message);
|
||||
|
||||
Reference in New Issue
Block a user