Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions apps/sim/app/api/workflows/[id]/execute/route.async.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,26 +194,6 @@ describe('workflow execute async route', () => {
)
})

it('rejects cross-origin session requests before authorization work', async () => {
const req = createMockRequest(
'POST',
{ input: { hello: 'world' } },
{
'Content-Type': 'application/json',
'Sec-Fetch-Site': 'cross-site',
}
)
const params = Promise.resolve({ id: 'workflow-1' })

const response = await POST(req, { params })
const body = await response.json()

expect(response.status).toBe(403)
expect(body.error).toBe('Access denied')
expect(mockAuthorizeWorkflowByWorkspacePermission).not.toHaveBeenCalled()
expect(mockEnqueue).not.toHaveBeenCalled()
})

it('rejects oversized request bodies before authorization work', async () => {
const req = createMockRequest(
'POST',
Expand Down
12 changes: 0 additions & 12 deletions apps/sim/app/api/workflows/[id]/execute/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
getTimeoutErrorMessage,
isTimeoutError,
} from '@/lib/core/execution-limits'
import { isCrossOriginSessionRequest } from '@/lib/core/security/same-origin'
import { generateRequestId } from '@/lib/core/utils/request'
import { SSE_HEADERS } from '@/lib/core/utils/sse'
import {
Expand Down Expand Up @@ -394,17 +393,6 @@ async function handleExecutePost(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security CSRF guard removed without replacement

This revert strips the only origin-header-based CSRF mitigation for session-cookie-authenticated workflow execution. Any page on any origin can now embed a form or fire a fetch with credentials to POST /api/workflows/[id]/execute, and the user's session cookie will be attached by the browser — triggering an arbitrary workflow under their identity. The deleted guard was narrowly scoped: it only fired when authType === AuthType.SESSION and the request was provably cross-origin via Sec-Fetch-Site or a mismatched Origin. If it was causing false-positives for a legitimate caller, that caller (API-key / public-API / internal-JWT) would never have been gated by the check in the first place. The PR description doesn't document what went wrong or what alternative protection replaces this.

try {
const auth = await checkHybridAuth(req, { requireWorkflowId: false })

// CSRF guard: reject session-cookie execution that is provably cross-origin
// (a different site driving the user's browser). Scoped to session auth —
// API-key / public-API / internal-JWT callers don't use cookies. This is not
// a defense against a non-browser client forging headers; that surface is
// covered by the credit and execution rate-limit gates.
if (auth.success && auth.authType === AuthType.SESSION && isCrossOriginSessionRequest(req)) {
reqLogger.warn('Rejected cross-origin session-authenticated execute request')
return NextResponse.json({ error: 'Access denied' }, { status: 403 })
}

const isMcpBridgeRequest =
auth.authType === AuthType.INTERNAL_JWT && req.headers.get(MCP_TOOL_BRIDGE_HEADER) === 'true'
const useMcpBridgeAuthenticatedUserAsActor =
Expand Down
53 changes: 0 additions & 53 deletions apps/sim/lib/core/security/same-origin.test.ts

This file was deleted.

36 changes: 0 additions & 36 deletions apps/sim/lib/core/security/same-origin.ts

This file was deleted.

Loading