v0.5.110: webhook execution speedups, SSRF patches #3524
Conversation
* fix(parallel): align integration with Parallel AI API docs * fix(parallel): keep processor subBlock ID for backwards compatibility * fix(parallel): move error field to top level per ToolResponse interface * fix(parallel): guard research_input and prevent domain leakage across operations * fix(parallel): make url/title nullable in types to match transformResponse * fix(parallel): revert search_queries param type to string for backwards compatibility
…very (#3500) * 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.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
…path (#3523) * fix(webhooks): eliminate redundant DB queries from webhook execution path * chore(webhooks): remove implementation-detail comments * fix(webhooks): restore auth-first ordering and add credential resolution warning - Revert parallel auth+preprocessing to sequential auth→preprocessing to prevent rate-limit exhaustion via unauthenticated requests - Add warning log when credential account resolution fails in background job * fix(webhooks): restore auth-before-reachability ordering and remove dead credentialAccountUserId field - Move reachability test back after auth to prevent path enumeration - Remove dead credentialAccountUserId from WebhookExecutionPayload - Simplify credential resolution condition in background job
PR SummaryMedium Risk Overview Webhooks & execution: Refactors webhook preprocessing to return Parallel AI alignment: Updates Parallel AI docs, block config, and tool implementations to match newer API behavior (search Written by Cursor Bugbot for commit 19ef526. Configure here. |
Greptile SummaryThis PR bundles three independent improvements: (1) aligns the Parallel AI integration with the current API docs (new Key highlights and concerns:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as Webhook Caller
participant Route as /api/webhooks/trigger/[path]
participant Processor as lib/webhooks/processor.ts
participant Preprocess as lib/execution/preprocessing.ts
participant Queue as Job Queue
participant BgJob as background/webhook-execution.ts
participant DB as Database
Client->>Route: POST /api/webhooks/trigger/:path
Route->>Processor: findAllWebhooksForPath()
Processor->>DB: Query webhooks + workflows
DB-->>Processor: foundWebhook, foundWorkflow
Processor-->>Route: webhooksForPath[]
Route->>Processor: verifyProviderAuth() [safeCompare for tokens]
Processor-->>Route: authError | null
Route->>Processor: checkWebhookPreprocessing(foundWorkflow, foundWebhook)
Processor->>Preprocess: preprocessExecution({workflowId, checkRateLimit:true, workflowRecord:foundWorkflow})
Preprocess->>DB: getWorkspaceBilledAccountUserId (billing)
DB-->>Preprocess: actorUserId + subscription
Preprocess-->>Processor: { success, actorUserId, workflowRecord, executionTimeout }
Processor-->>Route: WebhookPreprocessingResult { error:null, actorUserId }
Route->>Processor: queueWebhookExecution(webhook, workflow, body, req, { actorUserId })
Processor->>Queue: enqueue('webhook-execution', payload+workspaceId)
Queue-->>Processor: jobId
Processor-->>Route: 200 OK
Route-->>Client: 200 OK
Queue->>BgJob: executeWebhookJob(payload)
BgJob->>Preprocess: preprocessExecution({workflowId, checkRateLimit:false, skipUsageLimits:true})
Preprocess-->>BgJob: { workflowRecord, executionTimeout }
par Parallel DB fetches
BgJob->>DB: loadDeployedWorkflowState(workflowId, workspaceId)
BgJob->>DB: SELECT webhook WHERE id=webhookId
BgJob->>DB: resolveCredentialAccountUserId(credentialId) [if set]
end
DB-->>BgJob: workflowData, webhookRows, credentialAccountUserId
BgJob->>BgJob: formatWebhookInput + executeWorkflowCore()
BgJob->>DB: LoggingSession.complete()
|
Uh oh!
There was an error while loading. Please reload this page.