cloudflare / cloudflare/cloudflare-os

Email Gatekeeper lets users permanently reserve arbitrary mailbox names

Open
#62 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
9.9k
Forks
1.2k
Avg merge
1d 20h
Merged PRs (30d)
107

Description

## Summary

The Email Gatekeeper lets any authenticated user permanently reserve any valid mailbox local part. A user who claims a name first prevents the intended owner from claiming it later, and disconnecting does not release the name. On a deployment where all users can use the Email Gatekeeper, this creates a mailbox-name reservation/denial-of-service risk.

## Evidence

`packages/gatekeeper-email/src/email.ts` accepts a canonical `/mailbox/` URL in `GatekeeperUserImpl.getGatekeeperClassFor()` (around lines 386-438), then calls `EmailAddress.claim(userAccountId)` before recording the association in the caller's `UserAccount`.

`EmailAddress.claim()` (around lines 614-627) stores the first caller as `owner` and rejects every different caller. Its comments describe that owner as permanent. `GatekeeperUserImpl.revoke()` (around lines 441-449) deliberately disconnects hooks without releasing address claims, so the reservation survives disconnecting.

## Reproduction from the current source

1. Authenticate two different Workshop users on the same deployment.
2. Have user A create an Email Mailbox binding for `target-name`.
3. Have user B create a binding for the same canonical URL.
4. User B receives `This email address is claimed by another user`.
5. Repeat with other valid names. User A can reserve names without proving control of the corresponding email address.

This is based on the current source path and ownership comments; I have not run this against a deployed SMTP/Email Routing setup.

## Impact and design question

This is not an auth bypass: it prevents another user from claiming a name rather than granting the attacker access to the victim's mailbox. It is a namespace reservation problem that can block legitimate mailbox setup and may be exploitable by iterating names.

Please decide which policy is intended:

- only deployment admins may reserve mailbox names;
- claims should be released when an account disconnects, with safeguards for active routing; or
- users must prove control of an address before claiming it.

I am not proposing a PR because the correct fix changes mailbox ownership semantics, and `CONTRIBUTING.md` asks external contributors to report bugs rather than submit design-level patches.

Contributor guide

Open the contributing guide

Research direction

Start in packages/gatekeeper-email/src/email.ts by reading GatekeeperUserImpl.getGatekeeperClassFor(), EmailAddress.claim(), and GatekeeperUserImpl.revoke(), focusing on the ownership comments and association flow. Reproduce the two-user claim sequence from the issue, then confirm the intended ownership policy before defining completion criteria for preventing arbitrary permanent reservations.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend-api-design, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.