fix(security): re-auth on DB export/import + SSRF guard on web fetch
- /api/settings/database now requires current password (header for GET, body for POST) in addition to session; CLI-token requests exempt - add verifyDashboardPassword helper reusing login bcrypt check - profile UI prompts password via modal before export/import - /v1/web/fetch rejects internal/private/metadata targets via assertPublicUrl Refs GHSA-qvfm-67h2-2qfx, GHSA-qj3v-64wj-q825 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,6 +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";
|
||||
|
||||
/**
|
||||
* Handle web fetch (URL extraction) request for the SSE/Next.js server.
|
||||
@@ -78,6 +79,14 @@ export async function handleFetch(request) {
|
||||
return errorResponse(HTTP_STATUS.BAD_REQUEST, "Invalid URL format");
|
||||
}
|
||||
|
||||
// SSRF guard: reject internal/private/metadata targets
|
||||
try {
|
||||
assertPublicUrl(targetUrl);
|
||||
} catch (err) {
|
||||
log.warn("FETCH", "Blocked URL", { url: targetUrl });
|
||||
return errorResponse(HTTP_STATUS.BAD_REQUEST, err.message);
|
||||
}
|
||||
|
||||
// Combo expansion: providerInput may be a combo name → run fallback/round-robin across providers
|
||||
const combos = await getCombos();
|
||||
const comboModels = getComboModelsFromData(providerInput, combos);
|
||||
|
||||
Reference in New Issue
Block a user