Vulnerability Detail Report
Vulnerability Overview
- ZDID: ZD-2026-00808
- Vendor: SITCON 學生計算機年會
- Title: SITCON 學生計算機年會 tickets webhook management routes authorize one event ID but operate on path eventId
- Introduction: The public SITCON tickets webhook management routes authorize event access from query/body eventId while the handlers operate on the path eventId, creating a cross-event webhook management risk.
處理狀態
目前狀態
-
新提交
-
已審核
-
已通報
-
已修補
-
未複測
-
公開
處理歷程
- 2026/06/03 19:48:46 : 新提交 (由 老狼 更新此狀態)
- 2026/06/10 12:48:44 : 審核中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/09/18 15:32:56 : 已修補 (由 組織帳號 更新此狀態)
- 2026/09/19 03:00:11 : 公開 (由 HITCON ZeroDay 平台自動更新)
詳細資料
- ZDID:ZD-2026-00808
- 通報者:skyknow (老狼)
- 風險:中
- 類型:存取控制缺陷 (Broken Access Control)
參考資料
OWASP Top 10 - 2017 A5 - Broken Access Control
https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control
CWE-284: Improper Access Control
https://cwe.mitre.org/data/definitions/284.html
相關網址
https://github.com/sitcon-tw/tickets
https://github.com/sitcon-tw/tickets/blob/db4a3500c0331bdc5c204808399c52aa024b87e8/backend/routes/admin/webhooks.ts
https://github.com/sitcon-tw/tickets/blob/db4a3500c0331bdc5c204808399c52aa024b87e8/backend/middleware/auth.ts
https://github.com/sitcon-tw/tickets/blob/db4a3500c0331bdc5c204808399c52aa024b87e8/types/src/webhook.ts
敘述
Summary
The public sitcon-tw/tickets backend has webhook management routes under:
/api/admin/events/:eventId/webhook
These routes use requireEventAccess. That middleware authorizes event-scoped admins by checking:
query.eventId || params.id || body.eventId
It does not check params.eventId, which is the path parameter used by the webhook handlers.
The source therefore exposes two mismatch patterns:
POST /api/admin/events/:eventId/webhookcan be authorized bybody.eventId, while the handler creates the webhook for patheventId.GET,PUT, andDELETE /api/admin/events/:eventId/webhookcan be authorized by?eventId=<owned-event>, while the handlers read, update, or delete the webhook for patheventId.
If deployed as shown in source, an event-scoped organizer may be able to read, create, modify, or delete webhook configuration for an unrelated event.
Source evidence
backend/middleware/auth.tsreadsquery?.eventId || params?.id || body?.eventId.backend/routes/admin/webhooks.tsprotects webhook get/create/update/delete routes withpreHandler: [requireEventAccess].backend/routes/admin/webhooks.tsdestructureseventIdfromrequest.params.backend/routes/admin/webhooks.tsuses patheventIdforfindUnique, event lookup, existing-webhook checks, create, update, and delete.types/src/webhook.tsdefinesWebhookEndpointCreateRequestSchemawitheventId, allowing create authorization to be satisfied by body eventId.types/src/webhook.tsdefinesWebhookEndpointUpdateRequestSchemawithouteventId, so update can instead be authorized through queryeventId.backend/schemas.tsdefines get/update/delete webhook route schemas with path params only and no querystring schema for event authorization.backend/utils/webhook.tsshows webhook notifications include registration email, attendee email/name, form data, ticket info, and event info.
Local-only reproduction
I validated the control flow using local static modeling only:
python3 findings/20260603-1423-hitcon-sitcon-webhook-create-eventid-mismatch/local-repro.py
Result:
{
"observed_candidate_behavior": true,
"network_requests": 0,
"validation_mode": "LOCAL_SOURCE_STATIC_MODEL"
}
Modeled requests:
POST /api/admin/events/victim-event/webhook
body.eventId = owned-event
GET /api/admin/events/victim-event/webhook?eventId=owned-event
PUT /api/admin/events/victim-event/webhook?eventId=owned-event
DELETE /api/admin/events/victim-event/webhook?eventId=owned-event
eventAdmin permissions = [owned-event]
guard authorized event = owned-event
handler target event = victim-event
Impact
Unauthorized webhook creation or modification can route future registration or cancellation notifications for another event to an attacker-controlled HTTPS endpoint. Unauthorized read/delete can disclose webhook configuration metadata or disrupt webhook delivery for another event.
Based on the public source, webhook payloads can include registration IDs, registration email, attendee email/name, form data, event metadata, and ticket metadata.
This report is intentionally conservative: I validated public source and local control flow only. I did not prove live SITCON production exploitability.
Safety boundary
This report is based on public source and local-only analysis. I did not log in to SITCON, request SITCON production/private endpoints, create/update/delete/test/receive a real webhook, access real event/registration/ticket/email/form data, use scanners/fuzzing/DoS, contact SITCON, publish an issue, or open a PR.
修補建議
Use the same event ID for access control and mutation. Teach requireEventAccess to validate params.eventId, or create a dedicated requireEventAccessViaEventIdParam helper for webhook routes. Also remove eventId from the webhook create body schema if the path value is intended to be authoritative.