Skip to content

bug: GET /api/notify exposes user email addresses without authentication (PII leak) #2137

@nyxsky404

Description

@nyxsky404

Description

The GET /api/notify?user=<username> endpoint returns the full email address of any registered user to any unauthenticated caller. There is no authentication, authorization, or ownership verification. Anyone who knows (or guesses) a GitHub username can retrieve their private email from the database.

// Anyone can call:
// GET /api/notify?user=octocat
// Response includes the full email:
// { success: true, data: { username: "octocat", email: "user@private.com", frequency: "daily", ... } }

This is a Personally Identifiable Information (PII) leak that could enable targeted phishing, spam, or violate privacy regulations (GDPR, CCPA).

File: app/api/notify/route.ts (GET handler, lines ~80-130)

Note: Issue #2067 covers rate limiting and Zod validation for this endpoint, but does NOT mention the unauthenticated email exposure. This is a distinct security/privacy concern.

Steps to Reproduce

  1. Register notification preferences via POST /api/notify with a username and email
  2. From any browser or tool (no auth needed), call GET /api/notify?user=<that-username>
  3. Observe the full email address is returned in the JSON response
  4. Repeat with any other registered username to harvest emails

Expected Behavior

  • The GET endpoint should NOT expose the full email address to unauthenticated callers
  • At minimum, the email should be masked (e.g., u***r@gm***.com) in unauthenticated responses
  • Ideally, reading notification preferences should require some form of ownership verification (e.g., a token sent to the email, or session-based auth)
  • The endpoint should only return preference metadata (frequency, flags) without PII

Screenshots / Logs

N/A — this is a logic/design issue, not a visual bug.

Suggested Fix

Option A (Quick fix): Remove the email field from the GET response entirely, or mask it:

return NextResponse.json({
  success: true,
  message: "Notification preferences fetched successfully.",
  data: {
    username: notification.username,
    email: maskEmail(notification.email), // e.g., "u***@gmail.com"
    frequency: notification.frequency,
    preferences: { ... },
  },
});

Option B (Proper fix): Add authentication — require a secret token (generated on POST and emailed to the user) to read preferences.

Impact

  • Security: Any user's email can be enumerated by iterating known GitHub usernames
  • Privacy: Violates user expectations and potentially GDPR/CCPA
  • Trust: Users registering for notifications don't expect their email to be publicly queryable

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions