- Validate paste IDs against ^[a-f0-9]{16}$ before filesystem access
(blocks read/delete traversal via crafted URLs)
- Remove duplicate ALLOWED_IMAGE_EXTENSIONS that re-allowed SVG
(XSS via stored SVG); keep magic-byte validation
- Remove duplicate cleanup thread (two background loops were started)
- Unknown expiry keys now default to 1 day instead of never
- request.secure -> request.is_secure (werkzeug 3.x)
- Add gunicorn to requirements (Dockerfile CMD referenced it)
- 11 unit tests, ruff clean, MIT LICENSE, full README (was empty)
72 lines
1.9 KiB
Markdown
72 lines
1.9 KiB
Markdown
# paste-bin
|
|
|
|
A minimal, security-focused paste bin: share text, images, and files with
|
|
expiring links. Built with Flask and file-based storage (no database).
|
|
|
|
## Features
|
|
|
|
- Text, image, and file pastes with random 16-hex-char IDs
|
|
- Expiry options: 1 hour, 1 day, 1 week, 1 month, or never
|
|
- Automatic background cleanup of expired pastes
|
|
- Per-IP upload rate limiting (10 uploads / 60 s)
|
|
- Image magic-byte validation; SVG rejected (XSS prevention)
|
|
- Paste-ID format validation (blocks path traversal on read/delete)
|
|
- Security headers: CSP, HSTS, nosniff, frame deny, referrer policy
|
|
- Raw view, pretty view, and download endpoints per paste
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
python app.py
|
|
# visit http://localhost:8080
|
|
```
|
|
|
|
## Configuration
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `PORT` | `8080` | Web server port |
|
|
| `SECRET_KEY` | random | Flask secret key |
|
|
| `UPLOAD_FOLDER` | `./uploads` | Binary file storage |
|
|
| `STORE_FOLDER` | `./store` | Paste metadata + text content |
|
|
|
|
## Docker
|
|
|
|
```bash
|
|
docker build -t paste-bin .
|
|
docker run -p 8080:8080 \
|
|
-v paste-uploads:/app/uploads \
|
|
-v paste-store:/app/store \
|
|
paste-bin
|
|
```
|
|
|
|
Or with compose (mounts persistent volumes):
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
pip install -r requirements.txt pytest
|
|
pytest tests/ -v
|
|
```
|
|
|
|
Covers paste roundtrips, path-traversal blocking, SVG/magic-byte
|
|
validation, expiry parsing, and rate-limit setup.
|
|
|
|
## Security Notes
|
|
|
|
- Uploads are stored under a random ID; extension preserved only for
|
|
downloads with `Content-Disposition: attachment`.
|
|
- Text pastes are served as `text/plain` (never rendered as HTML).
|
|
- Images are served with `X-Content-Type-Options: nosniff` + restrictive CSP.
|
|
- Paste IDs are validated against `^[a-f0-9]{16}$` before any filesystem
|
|
access, so crafted URLs cannot read or delete arbitrary files.
|
|
|
|
## License
|
|
|
|
MIT — see [LICENSE](LICENSE).
|