Work
Personal Development/3 minutes read

E2EE File Uploader

An E2EE file uploader built as a way to study encryption.

What I Built

I built a file uploader because I was frustrated with Discord's file size limits and increasingly concerned about privacy in file-sharing services.

Simply building an uploader would have been boring, so I chose the stack with encryption practice in mind.

It began as an encryption study project, but as implementation progressed I ended up touching authentication, storage, CDN delivery, payments, and a public API.

Tech Stack

I built both the user-facing website and the admin site with Nuxt and Vuetify. Instead of preparing a separate backend, I used Nuxt's server directory so the whole application could run on Cloudflare Workers.

For file delivery, I use a separate CDN Worker running on Cloudflare Workers. This is because the storage service is Backblaze B2, an AWS S3-compatible storage service where egress can be free when data transfer goes through the Cloudflare CDN. (Reference: https://www.cloudflare.com/ja-jp/partners/technology-partners/backblaze/)

For the rest of the infrastructure, I use Cloudflare D1 for the database, Resend for email delivery, and Cloudflare Turnstile for bot protection, keeping running costs extremely low while maintaining stable behavior.

Encryption

The file body and metadata are encrypted client-side with AES-GCM. The server stores only encrypted data and the minimum values needed for operation. The decryption key is placed in the shared URL fragment so it is not sent through normal HTTP requests or server logs.

For users who want content previews in embeds such as Discord, I also made it possible to pass the key through a query parameter and have a dedicated OG endpoint decrypt and render the file server-side.

I also wanted to prioritize user privacy and avoid storing passwords whenever possible, so I implemented login with private keys and passkeys.

Session management is implemented with access tokens and refresh tokens. I built it myself without auth libraries, which was painful.

Upload And Delivery

Uploads are based on S3-compatible multipart upload so large files can be handled. I also use a Web Worker so the UI does not freeze during upload. Retention periods, download limits, per-plan capacity limits, and Turnstile-based abuse prevention are included. I wanted it to feel like a proper SaaS product, so I put real effort into those parts.

On the download side, a Cloudflare Workers CDN Worker verifies signed tokens and streams files from Backblaze B2. Token verification uses HMAC.

Payments And Admin

I added cryptocurrency top-ups and PayPal payments, and the admin screen lets me inspect users, files, revenue, and payment status. Payments are not just a matter of calling an API; I added multiple safeguards for failure handling, duplicate processing, and payment log retention. In fact, a user once charged back a PayPal payment, and because the logs were preserved, I won the dispute.

Use Of Generative AI

I used Codex during development. I subscribed to ChatGPT Plus on six accounts in total ($20/mo x 6) and kept running them to the limit. It helped a lot when finding security flaws, although there were also cases where I had to point out serious security issues myself.

After Building It

At first this was purely a learning project, but as development continued it became a product with multiple real features. I plan to keep developing it.

file.ez1.cc