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
3 changes: 3 additions & 0 deletions apps/web/server/lib/auth/login/getServerSideProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
const session = await getServerSession({ req });

const verifyJwt = (jwt: string) => {
// A missing key would encode to a zero-length secret, which jose happily
// verifies against - fail loudly instead (same pattern as next.config.ts).
if (!process.env.CALENDSO_ENCRYPTION_KEY) throw new Error("Please set CALENDSO_ENCRYPTION_KEY");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The check for CALENDSO_ENCRYPTION_KEY is placed inside verifyJwt, which is executed within a try-catch block inside getServerSideProps (lines 31-50). If the key is missing, the thrown error will be caught by the catch block and the user will be silently redirected to /auth/error?error=Invalid%20JWT%3A%20Please%20try%20again. This prevents the application from failing loudly as intended and masks a critical configuration issue as a user-facing authentication error.\n\nTo ensure the application fails loudly on misconfiguration, this check should be moved to the top of getServerSideProps (outside of the try-catch block).

const secret = new TextEncoder().encode(process.env.CALENDSO_ENCRYPTION_KEY);

return jwtVerify(jwt, secret, {
Expand Down
3 changes: 3 additions & 0 deletions packages/features/auth/lib/signJwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { SignJWT } from "jose";
import { WEBSITE_URL } from "@calcom/lib/constants";

const signJwt = async (payload: { email: string }) => {
// A missing key would encode to a zero-length secret, which jose happily
// signs with - fail loudly instead (same pattern as next.config.ts).
if (!process.env.CALENDSO_ENCRYPTION_KEY) throw new Error("Please set CALENDSO_ENCRYPTION_KEY");
const secret = new TextEncoder().encode(process.env.CALENDSO_ENCRYPTION_KEY);
return new SignJWT(payload)
.setProtectedHeader({ alg: "HS256" })
Expand Down
5 changes: 4 additions & 1 deletion packages/features/auth/lib/verifyCodeUnAuthenticated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ export const verifyCodeUnAuthenticated = async (email: string, code: string) =>
identifier: `emailVerifyCode.${hashEmail(email)}`,
});

// A missing key would degrade the seed to a pure function of the victim
// email (audit LO-05); fail loudly instead (same pattern as next.config.ts).
if (!process.env.CALENDSO_ENCRYPTION_KEY) throw new Error("Please set CALENDSO_ENCRYPTION_KEY");
const secret = createHash("md5")
.update(email + (process.env.CALENDSO_ENCRYPTION_KEY || ""))
.update(email + process.env.CALENDSO_ENCRYPTION_KEY)
.digest("hex");

const isValidToken = totpRawCheck(code, secret, { step: 900 });
Expand Down
Binary file removed packages/platform/atoms/static/Stripe secrets.png
Binary file not shown.
Loading