Skip to content

Commit 07fd134

Browse files
committed
fix(webhooks): fail closed when Teams chat-subscription webhook id is unavailable
Hardens the clientState check so a missing webhook id (theoretically unreachable, since the row is looked up by primary key) can never collapse the expected value to an empty string that a forged clientState could match.
1 parent 80e460d commit 07fd134

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

apps/sim/lib/webhooks/providers/microsoft-teams.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@ describe('microsoftTeamsHandler verifyAuth (chat subscription clientState)', ()
101101
expect(res?.status).toBe(401)
102102
})
103103

104+
it('fails closed when the webhook record has no id', async () => {
105+
const res = await microsoftTeamsHandler.verifyAuth!({
106+
webhook: {},
107+
workflow: {},
108+
request: makeRequest(makeNotificationBody('')),
109+
rawBody: makeNotificationBody(''),
110+
requestId: 'test-req',
111+
providerConfig: chatSubscriptionConfig,
112+
})
113+
expect(res?.status).toBe(401)
114+
})
115+
104116
it('does not require clientState for non-subscription trigger types', async () => {
105117
const res = await runVerifyAuth(JSON.stringify({ type: 'message', text: 'hi' }), {})
106118
expect(res).toBeNull()

apps/sim/lib/webhooks/providers/microsoft-teams.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,13 @@ export const microsoftTeamsHandler: WebhookProviderHandler = {
498498

499499
if (providerConfig.triggerId === 'microsoftteams_chat_subscription') {
500500
const expectedClientState = String(webhook.id ?? '')
501+
if (!expectedClientState) {
502+
logger.warn(
503+
`[${requestId}] Microsoft Teams chat subscription webhook missing id for clientState verification`
504+
)
505+
return new NextResponse('Unauthorized - Invalid clientState', { status: 401 })
506+
}
507+
501508
let notifications: unknown[] = []
502509
try {
503510
const parsed = JSON.parse(rawBody) as Record<string, unknown>

0 commit comments

Comments
 (0)