Skip to content

Patient Portal Uses Deprecated Rate-Limiter Draft Headers and Lacks Email Verification #1346

Description

@Pcmhacker-piro

Description

The patient portal auth limiter in server/routes/patient.routes.ts uses standardHeaders: "draft-8" which is a deprecated value in express-rate-limit. The "draft-8" string was removed in v7 of the library and causes compatibility issues. This can silently prevent rate limiting from functioning correctly on the patient authentication endpoints.

Additionally, the patient register endpoint has no email verification step — any user can register with any email address without confirmation, which could lead to fake/spam accounts consuming resources and poses a PHI security risk.

Steps to Reproduce

  1. Start the server and observe startup logs — no warning is emitted about the deprecated header option, but the behavior may be degraded.
  2. Attempt to register multiple patient accounts with arbitrary/non-existent email addresses — all succeed without verification.
  3. Check express-rate-limit documentation for standardHeaders — valid values are true, false, or "draft-6". The "draft-8" value is unrecognized since v7.

Expected Behavior

  • standardHeaders should be set to true (the recommended value that sends RateLimit-* headers per the latest spec).
  • Patient registration should either send an email verification link/code before activating the account, or at minimum validate that the email domain has a valid MX record.
  • Rate limit headers should be properly returned on patient auth responses.

Implementation Hints

Backend (server/routes/patient.routes.ts):

Fix the rate limiter:

const patientAuthLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  limit: 10,
  standardHeaders: true,          // was "draft-8"
  legacyHeaders: false,
  message: { error: "Too many attempts. Please try again later." },
});

Add email verification step after registration:

import { sendVerificationEmail } from "../email";

// After creating the patient user:
const verificationCode = Math.floor(100000 + Math.random() * 900000).toString();
// Store code in patient record or a separate verification store
await sendVerificationEmail(body.email, verificationCode);
return res.status(201).json({ message: "Account created. Please verify your email." });

Affected Files

  • server/routes/patient.routes.ts
  • server/email.ts (extend with patient verification support)

Labels

type:bug, level:beginner, backend, type:security

Metadata

Metadata

Labels

gssoc:approvedlevel:intermediateRequires standard familiarity with the codebase.type:bugSomething isn't working or throwing errors.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions