Update README.md

This commit is contained in:
Anaïs Saraiva
2026-08-15 00:42:22 +02:00
parent 12854202ca
commit 4848e7a3e7
+13 -8
View File
@@ -126,22 +126,26 @@ curl -F "password=hunter2" -F "[email protected]" http://localhost:3000/api/uploa
```json ```json
{ {
"id": "YOWJyhDXxhe3-L8MpEFBbA", "id": "xmK5lLMRErlN",
"key": "YOWJyhDXxhe3-L8MpEFBbAN_e93AqTrEMYutkmStScq5VfbQlrqUt9yHkqmeRp7OQ", "key": "xmK5lLMRErlN",
"url": "/d/YOWJyhDXxhe3-L8MpEFBbAN_e93AqTrEMYutkmStScq5VfbQlrqUt9yHkqmeRp7OQ", "url": "/d/xmK5lLMRErlN",
"originalName": "example.zip", "originalName": "example.zip",
"size": 123456, "size": 123456,
"protected": true "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`) ### `GET /d/:key` (also `HEAD`)
Every file is password-protected. Without a valid auth cookie the server shows a 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`. password prompt; a wrong or non-existent key returns a generic `404`.
```bash ```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 ### Password protection
@@ -185,10 +189,11 @@ paths or stack traces.
## Security model ## Security model
- **Secrets.** Each file gets a fresh 128-bit id + 256-bit secret via - **Secrets.** Each file gets a fresh 72-bit (9 random bytes) base64url key via
`crypto.randomBytes`. Keys are encoded base64url; brute forcing them is `crypto.randomBytes`, used as both the share id and the download key. Keys are
computationally infeasible. No timestamps, incrementing ids, `Math.random()`, encoded base64url; guessing one is infeasible at scale, and the required
or filenames are ever used as secrets. 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 - **At-rest.** Only a SHA-256 hash of the key is persisted. Comparisons use
constant-time `timingSafeEqual`. constant-time `timingSafeEqual`.
- **Passwords.** Every file has a password stored only as an **scrypt** hash - **Passwords.** Every file has a password stored only as an **scrypt** hash