Update README.md
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user