Skip to content

Security

How Temporary Email Messages Are Sanitized and Deleted

How inbound HTML is cleaned on the Worker and again in the browser, which attachments are stored, and how expiration deletes D1 rows and R2 objects.

3 min read

A disposable inbox still renders other people’s HTML. That is the uncomfortable part of building this product. The rule I shipped is: sanitize twice, store little, delete on a schedule, and never recover.

This page is about those mechanics on 10 Minute Temp Email. It is not a claim that the inbox is “unhackable,” and it is not a tutorial for hiding malware.

Two sanitizers, on purpose

Inbound MIME is parsed in the mail-ingest Worker. HTML goes through a Workers-safe cleaner that does not need a DOM:

  • Null bytes are removed
  • Tags that should never run in a mailbox (script, iframe, object, embed, form, svg, math, and similar) are stripped, including their inner content
  • Event-handler attributes (onclick and the rest) are removed
  • Remaining tags have unsafe attributes rewritten; javascript: URLs are neutralized
  • Bodies are truncated to a maximum character count

The browser does not trust that result. Before HTML is shown, the React client runs DOMPurify with a mail-oriented profile: layout tags such as style, center, and font may remain; script, iframe, form, svg, video, audio, and related tags are forbidden. The cleaned markup is shown in a sandboxed iframe (srcDoc), not as the parent page.

Plain-text fields (subject, sender, previews) are sanitized and length-capped separately. Previews prefer text, not raw HTML.

Remote HTTPS images in HTML may still load. cid: images are rewritten to authenticated attachment URLs so the reader does not need a raw content-id. That is convenience, not a promise that every image is harmless—treat unexpected mail as untrusted.

Attachments: allowlist, not “whatever arrived”

Not every part is stored. The service keeps a short list of types (JPEG, PNG, GIF, WebP, PDF, plain text, CSV, ZIP). SVG is excluded because it can carry script. There is a cap on how many attachments are stored per message and on per-file size, inside an overall message-size limit.

Downloads go through cookie-authenticated API routes. R2 object keys are not sent to the browser. If a type is not allowed, it does not appear as a file you can open here.

What deletion actually means

Expiration is not a cosmetic “this inbox is closed” banner with the bytes left on disk.

A cron on the ingest Worker runs every minute. In order it:

  1. Marks active mailboxes whose expires_at has passed
  2. Deletes expired message objects from R2 (including a count of missing objects)
  3. Deletes those message rows from D1, in batches
  4. Deletes mailbox rows that are expired or already marked deleted and have no remaining messages
  5. Prunes expired rate-limit rows

If you delete the mailbox from the UI, the session cookie is cleared immediately and the same cleanup path removes stored data. Either way, there is no restore. That is the answer to “can you recover my expired address?”—no.

Why recovery would be the wrong feature

People ask for it after they used a disposable address on an account they now want. Restoring mail would mean keeping it. Keeping it would contradict the 10-minute promise and increase how much third-party content this project holds.

If you still need the other site’s account, change their email setting to an address you own while you are logged in. This service cannot replay their message.

What you should still assume

Sanitization reduces drive-by script in the reader. It does not make phishing text safe. A PDF can still be a PDF. A ZIP can still contain files you should not open. The operator can see messages while the mailbox exists.

Use the inbox for low-stakes mail, not for material you cannot afford anyone to read.

Dinitha Ransidu, author

Software engineer

Dinitha Ransidu is a software engineer and the creator of 10 Minute Temp Email and ImgTask. He writes from first-hand work building this receive-only inbox on Cloudflare Workers, D1, and R2.

Share this article

Create a 10-minute inbox