7deba711d45154745ab0c4d06cc582ea9642fe56
All checks were successful
CI / test (push) Successful in 38s
Small data has unreliable entropy measurement due to sample size. MIN_ENTROPY_SIZE (default 256 bytes) sets the threshold.
FlaskPaste
A lightweight, secure pastebin REST API built with Flask.
Features
- Simple REST API - Create, retrieve, and delete pastes via HTTP
- Binary support - Upload text, images, archives, and other binary content
- Automatic MIME detection - Magic byte detection for common formats (PNG, JPEG, GIF, WebP, ZIP, PDF, GZIP)
- Client certificate authentication - Optional auth via
X-SSL-Client-SHA1header - Automatic expiry - Pastes expire after configurable period of inactivity
- Size limits - Configurable limits for anonymous and authenticated users
- Abuse prevention - Content-hash deduplication throttles repeated identical submissions
- Proof-of-work - Configurable computational puzzle prevents automated spam
- Security headers - HSTS, CSP, X-Frame-Options, Cache-Control, and more
- CLI client - Standalone
fpastecommand-line tool included - Request tracing - X-Request-ID support for log correlation
- Proxy trust validation - Optional shared secret for defense-in-depth
- Minimal dependencies - Flask only, SQLite built-in
Quick Start
# Clone and setup
git clone <repository>
cd flaskpaste
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Run development server
python run.py
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET / |
API information and usage | |
GET /health |
Health check (returns DB status) | |
GET /challenge |
Get proof-of-work challenge | |
POST / |
Create a new paste | |
GET /<id> |
Retrieve paste metadata | |
HEAD /<id> |
Retrieve paste metadata (headers only) | |
GET /<id>/raw |
Retrieve raw paste content | |
HEAD /<id>/raw |
Retrieve paste headers (no body) | |
DELETE /<id> |
Delete paste (requires auth) |
Usage Examples
Create a paste (raw text)
curl --data-binary @file.txt http://localhost:5000/
Create a paste (piped input)
echo "Hello, World!" | curl --data-binary @- http://localhost:5000/
Create a paste (JSON)
curl -H "Content-Type: application/json" \
-d '{"content":"Hello from JSON!"}' \
http://localhost:5000/
Retrieve paste metadata
curl http://localhost:5000/abc12345
Retrieve raw content
curl http://localhost:5000/abc12345/raw
Delete a paste (requires authentication)
curl -X DELETE \
-H "X-SSL-Client-SHA1: <your-cert-fingerprint>" \
http://localhost:5000/abc12345
CLI Client
A standalone command-line client fpaste is included (no external dependencies).
Basic Usage
# Create paste from file
./fpaste create file.txt
# Create paste from stdin
echo "Hello" | ./fpaste
# Get paste content
./fpaste get abc12345
# Get paste metadata
./fpaste get -m abc12345
# Delete paste (requires auth)
./fpaste delete abc12345
# Show server info
./fpaste info
Configuration
Set server URL and authentication via environment or config file:
# Environment variables
export FLASKPASTE_SERVER="https://paste.example.com"
export FLASKPASTE_CERT_SHA1="your-cert-fingerprint"
# Or config file (~/.config/fpaste/config)
server = https://paste.example.com
cert_sha1 = your-cert-fingerprint
Configuration
Configuration via environment variables:
| Variable | Default | Description |
|---|---|---|
FLASK_ENV |
development |
Environment (development, production, testing) |
FLASKPASTE_DB |
./data/pastes.db |
SQLite database path |
FLASKPASTE_ID_LENGTH |
12 |
Paste ID length (hex characters) |
FLASKPASTE_MAX_ANON |
3145728 (3 MiB) |
Max paste size for anonymous users |
FLASKPASTE_MAX_AUTH |
52428800 (50 MiB) |
Max paste size for authenticated users |
FLASKPASTE_EXPIRY |
432000 (5 days) |
Paste expiry in seconds |
FLASKPASTE_DEDUP_WINDOW |
3600 (1 hour) |
Dedup throttle window in seconds |
FLASKPASTE_DEDUP_MAX |
3 |
Max identical submissions per window |
FLASKPASTE_PROXY_SECRET |
(empty) | Shared secret for proxy trust validation |
FLASKPASTE_POW_DIFFICULTY |
20 |
PoW difficulty (leading zero bits, 0=disabled) |
FLASKPASTE_POW_TTL |
300 (5 min) |
PoW challenge validity period |
FLASKPASTE_POW_SECRET |
(auto) | Secret for signing PoW challenges |
Authentication
FlaskPaste uses client certificate authentication. When deployed behind a reverse proxy (nginx, Apache), configure the proxy to:
- Terminate TLS and validate client certificates
- Extract the certificate SHA1 fingerprint
- Pass it via the
X-SSL-Client-SHA1header
Example nginx configuration:
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header X-SSL-Client-SHA1 $ssl_client_fingerprint;
}
Authenticated users can:
- Upload larger pastes (50 MiB vs 3 MiB)
- Delete their own pastes
Production Deployment
Using Gunicorn
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:5000 wsgi:app
Using Podman/Docker
podman build -t flaskpaste .
podman run -d -p 5000:5000 -v flaskpaste-data:/app/data flaskpaste
See Containerfile for container build configuration.
Development
Running Tests
pip install pytest pytest-cov
pytest tests/ -v
Test Coverage
pytest tests/ --cov=app --cov-report=term-missing
Project Structure
flaskpaste/
├── app/
│ ├── __init__.py # Flask app factory
│ ├── config.py # Configuration classes
│ ├── database.py # SQLite management
│ └── api/
│ ├── __init__.py # Blueprint setup
│ └── routes.py # API endpoints
├── tests/ # Test suite
├── data/ # SQLite database
├── run.py # Development server
├── wsgi.py # Production WSGI entry
├── Containerfile # Podman/Docker build
└── requirements.txt # Dependencies
Security Considerations
- Input validation - Paste IDs are hex-only, auth headers validated
- MIME sanitization - Content-Type headers are sanitized
- SQL injection protection - Parameterized queries throughout
- Ownership enforcement - Only owners can delete their pastes
- Size limits - Prevents resource exhaustion attacks
- Abuse prevention - Content-hash deduplication prevents spam flooding
- Security headers - HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Cache-Control
- Request tracing - X-Request-ID for log correlation and debugging
- Proxy trust - Optional
X-Proxy-Secretvalidation to prevent header spoofing
License
MIT
Description
Languages
Python
95%
Shell
4.2%
Makefile
0.4%
Dockerfile
0.4%