File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11import { createLogger } from '@sim/logger'
22import { getErrorMessage , toError } from '@sim/utils/errors'
33import { GitLabIcon } from '@/components/icons'
4+ import { isSameOrigin } from '@/lib/core/utils/validation'
45import { fetchWithRetry , VALIDATE_RETRY_OPTIONS } from '@/lib/knowledge/documents/utils'
56import type { ConnectorConfig , ExternalDocument , ExternalDocumentList } from '@/connectors/types'
67import { computeContentHash , joinTagArray , parseTagDate } from '@/connectors/utils'
@@ -103,21 +104,6 @@ function parseNextLink(linkHeader: string | null): string | undefined {
103104 return undefined
104105}
105106
106- /**
107- * Returns true when `candidate` resolves to the same origin as `base`. Used to
108- * pin a persisted pagination cursor to the configured GitLab host before
109- * following it with an `Authorization` header, so a tampered or corrupted
110- * `fileNextUrl` cannot exfiltrate the access token to an attacker-controlled
111- * host. Returns false on any unparseable URL.
112- */
113- function isSameOrigin ( candidate : string , base : string ) : boolean {
114- try {
115- return new URL ( candidate ) . origin === new URL ( base ) . origin
116- } catch {
117- return false
118- }
119- }
120-
121107/**
122108 * Returns the ordered list of active sync phases for a content-type choice.
123109 */
Original file line number Diff line number Diff line change 11import { getBaseUrl } from './urls'
22
33/**
4- * Checks if a URL is same-origin with the application's base URL.
5- * Used to prevent open redirect vulnerabilities.
4+ * Checks if a URL is same-origin with a base URL. Defaults to the application's
5+ * base URL, used to prevent open redirect vulnerabilities; pass an explicit
6+ * `base` to pin a URL to another trusted origin (e.g. a configured API host)
7+ * before following it with credentials.
68 *
79 * @param url - The URL to validate
10+ * @param base - The origin to compare against (defaults to the app base URL)
811 * @returns True if the URL is same-origin, false otherwise (secure default)
912 */
10- export function isSameOrigin ( url : string ) : boolean {
13+ export function isSameOrigin ( url : string , base : string = getBaseUrl ( ) ) : boolean {
1114 try {
12- const targetUrl = new URL ( url )
13- const appUrl = new URL ( getBaseUrl ( ) )
14- return targetUrl . origin === appUrl . origin
15+ return new URL ( url ) . origin === new URL ( base ) . origin
1516 } catch {
1617 return false
1718 }
Original file line number Diff line number Diff line change @@ -19,6 +19,7 @@ import {
1919} from '@/lib/core/utils/stream-limits'
2020import { getBaseUrl , getInternalApiBaseUrl } from '@/lib/core/utils/urls'
2121import { isUserFile } from '@/lib/core/utils/user-file'
22+ import { isSameOrigin } from '@/lib/core/utils/validation'
2223import { SIM_VIA_HEADER , serializeCallChain } from '@/lib/execution/call-chain'
2324import { parseMcpToolId } from '@/lib/mcp/utils'
2425import { resolveWorkspaceFileReference } from '@/lib/uploads/contexts/workspace/workspace-file-manager'
@@ -1364,17 +1365,7 @@ function isErrorResponse(
13641365 * the platform's own workflow execution endpoints via absolute URL.
13651366 */
13661367function isSelfOriginUrl ( url : string ) : boolean {
1367- try {
1368- const targetOrigin = new URL ( url ) . origin
1369- const publicOrigin = new URL ( getBaseUrl ( ) ) . origin
1370- if ( targetOrigin === publicOrigin ) return true
1371-
1372- const internalOrigin = new URL ( getInternalApiBaseUrl ( ) ) . origin
1373- if ( targetOrigin === internalOrigin ) return true
1374- } catch {
1375- return false
1376- }
1377- return false
1368+ return isSameOrigin ( url , getBaseUrl ( ) ) || isSameOrigin ( url , getInternalApiBaseUrl ( ) )
13781369}
13791370
13801371/**
You can’t perform that action at this time.
0 commit comments