Skip to content

Commit b2cf0bc

Browse files
committed
fix(security): allow HTTP webhooks and fix misleading MCP error docs
- Add allowHttp option to validateExternalUrl, validateUrlWithDNS, and secureFetchWithValidation to support HTTP webhook URLs - Pass allowHttp: true for webhook delivery and test endpoints - Fix misleading JSDoc on createMcpErrorResponse (doesn't log errors) - Mark unused error param with underscore prefix
1 parent 28f3f1c commit b2cf0bc

File tree

5 files changed

+21
-8
lines changed

5 files changed

+21
-8
lines changed

apps/sim/app/api/workspaces/[id]/notifications/[notificationId]/test/route.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ async function testWebhook(subscription: typeof workspaceNotificationSubscriptio
144144
headers,
145145
body,
146146
timeout: 10000,
147+
allowHttp: true,
147148
},
148149
'webhookUrl'
149150
)

apps/sim/background/workspace-notification-delivery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ async function deliverWebhook(
216216
headers,
217217
body,
218218
timeout: 30000,
219+
allowHttp: true,
219220
},
220221
'webhookUrl'
221222
)

apps/sim/lib/core/security/input-validation.server.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ function isPrivateOrReservedIP(ip: string): boolean {
5454
*/
5555
export async function validateUrlWithDNS(
5656
url: string | null | undefined,
57-
paramName = 'url'
57+
paramName = 'url',
58+
options: { allowHttp?: boolean } = {}
5859
): Promise<AsyncValidationResult> {
59-
const basicValidation = validateExternalUrl(url, paramName)
60+
const basicValidation = validateExternalUrl(url, paramName, options)
6061
if (!basicValidation.isValid) {
6162
return basicValidation
6263
}
@@ -404,10 +405,12 @@ export async function secureFetchWithPinnedIP(
404405
*/
405406
export async function secureFetchWithValidation(
406407
url: string,
407-
options: SecureFetchOptions = {},
408+
options: SecureFetchOptions & { allowHttp?: boolean } = {},
408409
paramName = 'url'
409410
): Promise<SecureFetchResponse> {
410-
const validation = await validateUrlWithDNS(url, paramName)
411+
const validation = await validateUrlWithDNS(url, paramName, {
412+
allowHttp: options.allowHttp,
413+
})
411414
if (!validation.isValid) {
412415
throw new Error(validation.error)
413416
}

apps/sim/lib/core/security/input-validation.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,8 @@ export function validateJiraIssueKey(
676676
*/
677677
export function validateExternalUrl(
678678
url: string | null | undefined,
679-
paramName = 'url'
679+
paramName = 'url',
680+
options: { allowHttp?: boolean } = {}
680681
): ValidationResult {
681682
if (!url || typeof url !== 'string') {
682683
return {
@@ -709,7 +710,14 @@ export function validateExternalUrl(
709710
}
710711
}
711712

712-
if (protocol !== 'https:' && !(protocol === 'http:' && isLocalhost)) {
713+
if (options.allowHttp) {
714+
if (protocol !== 'https:' && protocol !== 'http:') {
715+
return {
716+
isValid: false,
717+
error: `${paramName} must use http:// or https:// protocol`,
718+
}
719+
}
720+
} else if (protocol !== 'https:' && !(protocol === 'http:' && isLocalhost)) {
713721
return {
714722
isValid: false,
715723
error: `${paramName} must use https:// protocol`,

apps/sim/lib/mcp/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ export const MCP_CLIENT_CONSTANTS = {
5151
/**
5252
* Create standardized MCP error response.
5353
* Always returns the defaultMessage to clients to prevent leaking internal error details.
54-
* The original error is logged server-side for debugging.
54+
* Callers are responsible for logging the original error before calling this function.
5555
*/
5656
export function createMcpErrorResponse(
57-
error: unknown,
57+
_error: unknown,
5858
defaultMessage: string,
5959
status = 500
6060
): NextResponse {

0 commit comments

Comments
 (0)