You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A comprehensive security audit identified 4 Critical, 7 High, and 11 Medium severity vulnerabilities across the codebase. The most urgent issues involve credential exposure, rate limiter bypass, CORS misconfiguration, and missing security headers.
user: {include: {credentials: true,// FETCHES ALL CREDENTIAL FIELDS INCLUDING `key`},},
The bookingInclude object uses include: { credentials: true } on the user relation. The Prisma Credential model has a key field of type Json that stores OAuth tokens, API keys, and other secrets. Using include: true fetches ALL fields including key. This data flows through the tRPC pipeline and could be serialized to API responses.
Impact: OAuth access tokens, refresh tokens, API keys, and other credential secrets could be exposed to any authenticated user who can view bookings.
Fix: Replace include: { credentials: true } with a select that explicitly lists needed fields, excluding key.
2. Rate Limiter Fails Open (Bypasses All Rate Limiting)
If UNKEY_ROOT_KEY is unset or the Unkey service is down, all rate limiting is silently disabled. The onError handler (line 55) also returns success: true, meaning any Unkey outage removes all rate limiting from the entire application.
Impact: Complete bypass of all rate limiting on auth endpoints, booking creation, email sending, SMS, and API calls.
Fix: Fail closed (reject requests) when the rate limiter is unavailable, or implement a local fallback rate limiter.
Any malicious website can make authenticated cross-origin requests to the Cal.com API. Combined with cookieParser() middleware, this creates a CSRF attack surface for cookie-based auth flows.
Impact: Cross-site request forgery, data theft from authenticated sessions.
Fix: Configure CORS to only allow specific trusted origins.
4. Missing Security Headers (No CSP, No HSTS)
File:apps/web/next.config.ts:371-499
Only X-Content-Type-Options and Referrer-Policy are set globally. X-Frame-Options: DENY only applies to /auth/* and /signup. Missing:
Security Audit Report - Cal.diy Codebase
Executive Summary
A comprehensive security audit identified 4 Critical, 7 High, and 11 Medium severity vulnerabilities across the codebase. The most urgent issues involve credential exposure, rate limiter bypass, CORS misconfiguration, and missing security headers.
CRITICAL Findings
1. credential.key Exposed in tRPC Booking Queries
File:
packages/trpc/server/routers/viewer/bookings/util.ts:42The
bookingIncludeobject usesinclude: { credentials: true }on the user relation. The PrismaCredentialmodel has akeyfield of typeJsonthat stores OAuth tokens, API keys, and other secrets. Usinginclude: truefetches ALL fields includingkey. This data flows through the tRPC pipeline and could be serialized to API responses.Impact: OAuth access tokens, refresh tokens, API keys, and other credential secrets could be exposed to any authenticated user who can view bookings.
Fix: Replace
include: { credentials: true }with aselectthat explicitly lists needed fields, excludingkey.2. Rate Limiter Fails Open (Bypasses All Rate Limiting)
File:
packages/lib/rateLimit.ts:36-41If
UNKEY_ROOT_KEYis unset or the Unkey service is down, all rate limiting is silently disabled. TheonErrorhandler (line 55) also returnssuccess: true, meaning any Unkey outage removes all rate limiting from the entire application.Impact: Complete bypass of all rate limiting on auth endpoints, booking creation, email sending, SMS, and API calls.
Fix: Fail closed (reject requests) when the rate limiter is unavailable, or implement a local fallback rate limiter.
3. CORS
origin: "*"on API v2File:
apps/api/v2/src/bootstrap.ts:44Any malicious website can make authenticated cross-origin requests to the Cal.com API. Combined with
cookieParser()middleware, this creates a CSRF attack surface for cookie-based auth flows.Impact: Cross-site request forgery, data theft from authenticated sessions.
Fix: Configure CORS to only allow specific trusted origins.
4. Missing Security Headers (No CSP, No HSTS)
File:
apps/web/next.config.ts:371-499Only
X-Content-Type-OptionsandReferrer-Policyare set globally.X-Frame-Options: DENYonly applies to/auth/*and/signup. Missing:Impact: No protection against XSS, clickjacking (on most pages), or protocol downgrade attacks.
HIGH Findings
5. SSRF via User-Controlled ICS Feed URLs
File:
packages/app-store/ics-feedcalendar/lib/CalendarService.ts:86User-configured URLs fetched server-side without URL validation. Could target internal services (
169.254.169.254,localhost).6. SSRF via Avatar API Prefill
File:
packages/features/auth/signup/utils/prefillAvatar.ts:14URLs from external Avatar API fetched without validation.
7. Non-Timing-Safe HMAC Comparison (HitPay Webhook)
File:
packages/app-store/hitpay/api/webhook.ts:107Should use
crypto.timingSafeEqual()(as BTCPay webhook correctly does).8. Weak PRNG for Random Strings
File:
packages/lib/random.ts:11Math.random()is cryptographically insecure. Should usecrypto.randomBytes().9. MD5 Used for Email Hashing
File:
packages/trpc/server/routers/viewer/me/get.handler.ts:122MD5 is cryptographically broken.
10. postMessage Without Origin Validation (Embed SDK)
Files:
packages/embeds/embed-core/src/embed.ts:1565,embed-iframe.ts:559All postMessage handlers lack origin checks. Outbound messages use
targetOrigin="*". The codebase has a TODO acknowledging this gap.11. Unauthenticated AES Encryption (No GCM)
File:
packages/lib/crypto.ts:3Vulnerable to padding oracle attacks. Should use
aes-256-gcm.MEDIUM Findings
12. HttpExceptionFilter Leaks Internal Details
File:
apps/api/v2/src/filters/http-exception.filter.ts:35Returns
exception.getResponse()directly to clients without environment check.13. ValidationPipe Leaks Target & Value
File:
apps/api/v2/src/bootstrap.ts:63-64Leaks full request object and submitted values in error responses.
14. Swagger UI Publicly Accessible
File:
apps/api/v2/src/swagger/generate-swagger.ts:38-41No auth gate when
DOCS_URLenv var is unset.15. SameSite=none on Session Cookies
File:
packages/lib/default-cookies.ts:25Weakens CSRF protection for iframe embedding support.
16. JSON.parse Before OAuth State Verification
File:
packages/app-store/_utils/oauth/decodeOAuthState.ts:12State parsed before HMAC check. Several apps (stripe, basecamp3, dub, webex, tandem) skip nonce verification entirely.
17. Open Redirect (Signup)
File:
apps/web/modules/signup-view.tsx:298callbackUrlsearch parameter concatenated into redirect URL withoutgetSafeRedirectUrl()validation.18. Open Redirect (Stripe)
File:
apps/api/v2/src/modules/stripe/controllers/stripe.controller.ts:58returnToquery parameter taken directly from user input without validation.19. Env Var JSON Injection
File:
packages/lib/constants.ts:140-14120. Script Injection via Env Vars
File:
apps/web/app/(use-page-wrapper)/layout.tsx:9-35NEXT_PUBLIC_HEAD_SCRIPTSandNEXT_PUBLIC_BODY_SCRIPTSinjected viadangerouslySetInnerHTML.21. Inline Script Interpolation (Locale)
File:
apps/web/pages/_document.tsx:61__html: `window.calNewLocale = "${newLocale}";`Locale from cookie interpolated without escaping.
22. Overly Permissive
includein API v2 RepositoriesFile:
apps/api/v2/src/modules/teams/event-types/teams-event-types.repository.tsUses
include: { users: true, owner: true }fetching all fields including sensitive ones.Positive Findings
crypto.timingSafeEqual()timingSafeEqualrandomBytes(32)and HttpOnly cookiesgetSafeRedirectUrl()correctly validates redirect URLs on login pageRecommended Priority
This audit was performed by automated security scanning of the codebase.