From 4848e7a3e74bdd09a74ef553cdf63ccf03476b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=C3=AFs=20Saraiva?= <53227802+Kisakay@users.noreply.github.com> Date: Sat, 15 Aug 2026 00:42:22 +0200 Subject: [PATCH] Update README.md --- README.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b20e027..144a984 100644 --- a/README.md +++ b/README.md @@ -126,22 +126,26 @@ curl -F "password=hunter2" -F "file=@secret.zip" http://localhost:3000/api/uploa ```json { - "id": "YOWJyhDXxhe3-L8MpEFBbA", - "key": "YOWJyhDXxhe3-L8MpEFBbAN_e93AqTrEMYutkmStScq5VfbQlrqUt9yHkqmeRp7OQ", - "url": "/d/YOWJyhDXxhe3-L8MpEFBbAN_e93AqTrEMYutkmStScq5VfbQlrqUt9yHkqmeRp7OQ", + "id": "xmK5lLMRErlN", + "key": "xmK5lLMRErlN", + "url": "/d/xmK5lLMRErlN", "originalName": "example.zip", "size": 123456, "protected": true } ``` +`id` and `key` are the same 12-character base64url token (~72 bits of entropy); +the short length keeps share URLs tidy, and the required password adds a second +factor of protection. + ### `GET /d/:key` (also `HEAD`) Every file is password-protected. Without a valid auth cookie the server shows a password prompt; a wrong or non-existent key returns a generic `404`. ```bash -curl -O http://localhost:3000/d/YOWJyh...7OQ # prompts for password first +curl -O http://localhost:3000/d/xmK5lLMRErlN # prompts for password first ``` ### Password protection @@ -185,10 +189,11 @@ paths or stack traces. ## Security model -- **Secrets.** Each file gets a fresh 128-bit id + 256-bit secret via - `crypto.randomBytes`. Keys are encoded base64url; brute forcing them is - computationally infeasible. No timestamps, incrementing ids, `Math.random()`, - or filenames are ever used as secrets. +- **Secrets.** Each file gets a fresh 72-bit (9 random bytes) base64url key via + `crypto.randomBytes`, used as both the share id and the download key. Keys are + encoded base64url; guessing one is infeasible at scale, and the required + password is an added second factor. No timestamps, incrementing ids, + `Math.random()`, or filenames are ever used as secrets. - **At-rest.** Only a SHA-256 hash of the key is persisted. Comparisons use constant-time `timingSafeEqual`. - **Passwords.** Every file has a password stored only as an **scrypt** hash