mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
* fix(security): add SSRF protection to database tools and webhook delivery * fix(security): address review comments on SSRF PR - Remove Promise.race timeout pattern to avoid unhandled rejections (http.request timeout is sufficient for webhook delivery) - Use safeCompare in verifyCronAuth instead of inline HMAC logic - Strip IPv6 brackets before validateDatabaseHost in Redis route * 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 * fix(security): forward allowHttp option through redirect validation Pass allowHttp to validateUrlWithDNS in the redirect handler of secureFetchWithPinnedIP so HTTP-to-HTTP redirects work when allowHttp is enabled for webhook delivery. * fix(security): block localhost when allowHttp is enabled When allowHttp is true (user-supplied webhook URLs), explicitly block localhost/loopback in both validateExternalUrl and validateUrlWithDNS to prevent SSRF against internal services. * fix(security): always strip multi-line content in sanitizeConnectionError Take the first line of the error message regardless of length to prevent leaking sensitive data from multi-line error messages.
99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import { WebhookIcon } from '@/components/icons'
|
|
import type { TriggerConfig } from '@/triggers/types'
|
|
|
|
export const genericWebhookTrigger: TriggerConfig = {
|
|
id: 'generic_webhook',
|
|
name: 'Generic Webhook',
|
|
provider: 'generic',
|
|
description: 'Receive webhooks from any service or API',
|
|
version: '1.0.0',
|
|
icon: WebhookIcon,
|
|
|
|
subBlocks: [
|
|
{
|
|
id: 'webhookUrlDisplay',
|
|
title: 'Webhook URL',
|
|
type: 'short-input',
|
|
readOnly: true,
|
|
showCopyButton: true,
|
|
useWebhookUrl: true,
|
|
placeholder: 'Webhook URL will be generated',
|
|
mode: 'trigger',
|
|
},
|
|
{
|
|
id: 'requireAuth',
|
|
title: 'Require Authentication',
|
|
type: 'switch',
|
|
description: 'Require authentication for all webhook requests',
|
|
defaultValue: true,
|
|
mode: 'trigger',
|
|
},
|
|
{
|
|
id: 'token',
|
|
title: 'Authentication Token',
|
|
type: 'short-input',
|
|
placeholder: 'Enter an auth token',
|
|
description: 'Token used to authenticate webhook requests via Bearer token or custom header',
|
|
password: true,
|
|
required: false,
|
|
value: () => crypto.randomUUID(),
|
|
mode: 'trigger',
|
|
},
|
|
{
|
|
id: 'secretHeaderName',
|
|
title: 'Secret Header Name (Optional)',
|
|
type: 'short-input',
|
|
placeholder: 'X-Secret-Key',
|
|
description:
|
|
'Custom HTTP header name for the auth token. If blank, uses "Authorization: Bearer TOKEN"',
|
|
required: false,
|
|
mode: 'trigger',
|
|
},
|
|
{
|
|
id: 'inputFormat',
|
|
title: 'Input Format',
|
|
type: 'input-format',
|
|
description:
|
|
'Define the expected JSON input schema for this webhook (optional). Use type "file[]" for file uploads.',
|
|
mode: 'trigger',
|
|
},
|
|
{
|
|
id: 'triggerSave',
|
|
title: '',
|
|
type: 'trigger-save',
|
|
hideFromPreview: true,
|
|
mode: 'trigger',
|
|
triggerId: 'generic_webhook',
|
|
},
|
|
{
|
|
id: 'triggerInstructions',
|
|
title: 'Setup Instructions',
|
|
hideFromPreview: true,
|
|
type: 'text',
|
|
defaultValue: [
|
|
'Copy the webhook URL and use it in your external service or API.',
|
|
'Configure your service to send webhooks to this URL.',
|
|
'The webhook will receive any HTTP method (GET, POST, PUT, DELETE, etc.).',
|
|
'All request data (headers, body, query parameters) will be available in your workflow.',
|
|
'If authentication is enabled, include the token in requests using either the custom header or "Authorization: Bearer TOKEN".',
|
|
'Common fields like "event", "id", and "data" will be automatically extracted from the payload when available.',
|
|
]
|
|
.map(
|
|
(instruction, index) =>
|
|
`<div class="mb-3"><strong>${index + 1}.</strong> ${instruction}</div>`
|
|
)
|
|
.join(''),
|
|
mode: 'trigger',
|
|
},
|
|
],
|
|
|
|
outputs: {},
|
|
|
|
webhook: {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
},
|
|
}
|