One-time download codes. Zero leaks.
Upload a document URL β Get 5 unique codes β Share securely.
| Icon | Feature | What it does |
|---|---|---|
| π€ | Upload & Share | Submit a document URL, get 5 unique one-time download codes |
| π | Secure by Design | Each code expires after 7 days or first use β never reused |
| π | Dashboard | Manage documents, generate new codes, track usage, delete |
| π | Recovery | 10-character recovery codes if you forget your user ID |
| π‘οΈ | Session Auth | Log in once, no repeated password prompts |
| π§± | CSRF Protection | All forms protected against cross-site request forgery |
| β±οΈ | Rate Limiting | Prevents brute-force attacks on auth and code endpoints |
| π | Account Lockout | 5 failed attempts β temporary block |
| β | URL Validation | Blocks javascript:, localhost, private IPs |
| ποΈ Layer | π οΈ Technology |
|---|---|
| Framework | |
| Database | |
| Auth | |
| Security | |
| Deployment |
π¦ document_sharing_app/
βββ π app.py # Main Flask application
βββ ποΈ schema.sql # Supabase/PostgreSQL schema + migrations
βββ π requirements.txt # Python dependencies
βββ π .env # Environment variables (credentials)
βββ π README.md # This file
βββ π LICENSE # MIT License
βββ π document_sharing_app_security_audit.md # Full security audit
βββ π¨ static/
β βββ π style.css # Application styles
β βββ β‘ script.js # Client-side JavaScript
βββ π templates/
βββ π base.html # Layout template (nav, fonts, icons)
βββ π€ index.html # Upload page + registration receipt
βββ π existing.html # Login form + user dashboard
βββ π forget.html # Recover user ID + recovery codes
βββ β¬οΈ download.html # Code redemption page
1οΈβ£ Register β Go to /, enter document URL, name & password
2οΈβ£ Get Codes β App generates 5 unique one-time download codes
3οΈβ£ Share β Send any code to your intended recipient
4οΈβ£ Manage β Log in at /existing to view docs, generate codes, delete
5οΈβ£ Recover β Used /forget to retrieve your user ID
1οΈβ£ Go to /download
2οΈβ£ Enter the code you received
3οΈβ£ β
Valid β Document URL is revealed
4οΈβ£ β Code marked used β cannot be reused
β Sign up
git clone https://github.com/ocean-master0/document_sharing_app.git
cd document_sharing_app
pip install -r requirements.txt| βοΈ Setting | π Where to find it |
|---|---|
SUPABASE_URL |
Project Settings β API β Project URL |
SUPABASE_ANON_KEY |
Project Settings β API β anon public key |
Create a .env file in the project root:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=use your-anon-public-key-here
SECRET_KEY=your-64-character-hex-secret-key
# Optional:
# ENVIRONMENT=production
# REDIS_URL=redis://your-redis-host:6379π‘ Generate a secure key:
python -c "import secrets; print(secrets.token_hex(32))"
| Step | Action |
|---|---|
| 1 | Open Supabase Dashboard β SQL Editor |
| 2 | Copy contents of schema.sql |
| 3 | Paste & click Run |
Creates all tables, indexes, and permissions. β
python app.pyOpens at http://0.0.0.0:5000 π
gunicorn \
--workers 4 \
--worker-class gthread \
--threads 2 \
--bind 0.0.0.0:$PORT \
--timeout 30 \
--max-requests 1000 \
app:appSet ENVIRONMENT=production to enable:
| π£οΈ Method | π€οΈ Route | π Description | π Auth |
|---|---|---|---|
GET/POST |
/ |
Register + upload document | β |
GET/POST |
/existing |
Login / Dashboard | β |
POST |
/login |
Login endpoint | β |
GET |
/logout |
Logout | β |
GET/POST |
/forget |
Recover user ID | β |
GET/POST |
/download |
Redeem download code | β* |
POST |
/download_codes |
Download codes as .txt | β |
POST |
/download_forget_codes |
Download recovery codes as .txt | β |
GET |
/.well-known/security.txt |
Security disclosure | β |
*CSRF exempt β codes are single-use by nature.
| π Feature | βοΈ Implementation | π― Status |
|---|---|---|
| Password storage | bcrypt with salt (12 rounds) | π’ |
| Download codes | SHA-256 hashed before DB storage | π’ |
| Recovery codes | SHA-256 hashed before DB storage | π’ |
| Sessions | Signed cookies with 8-hour expiry | π’ |
| CSRF | Flask-WTF CSRFProtect on all POST requests |
π’ |
| Rate limiting | Per-IP, 10 req/min auth, 20 req/min download | π’ |
| Account lockout | 5 failed attempts β temporary block | π’ |
| URL validation | Only http/https, blocks private/internal IPs | π’ |
| Security headers | CSP, HSTS, XSS Protection, Referrer Policy | π’ |
| Timing attacks | Constant-time compare + dummy bcrypt | π’ |
| Log injection | CRLF sanitized in log messages | π’ |
π Click to view the full security audit
A comprehensive security audit identified 19 vulnerabilities (2 critical, 6 high, 5 medium, 4 low, 2 info) β all have been fixed.
See document_sharing_app_security_audit.md for the complete report.
| π Column | π·οΈ Type | π Description |
|---|---|---|
user_id_hash |
TEXT (PK) |
SHA-256 of user ID |
password_hash |
TEXT |
bcrypt hashed password |
created_at |
TIMESTAMPTZ |
Registration timestamp |
| π Column | π·οΈ Type | π Description |
|---|---|---|
id |
BIGSERIAL (PK) |
Auto-incrementing ID |
url |
TEXT |
Document URL |
doc_name |
TEXT |
Document name |
user_name |
TEXT |
Owner's display name |
user_id_hash |
TEXT (FK) |
Owner's user ID hash |
user_id |
TEXT |
Owner's user ID (display) |
code |
TEXT (UNIQUE) |
SHA-256 hashed download code |
used |
BOOLEAN |
Whether code has been used |
created_at |
TIMESTAMPTZ |
Creation timestamp |
| π Column | π·οΈ Type | π Description |
|---|---|---|
id |
BIGSERIAL (PK) |
Auto-incrementing ID |
user_id_hash |
TEXT (FK) |
Owner's user ID hash |
user_id |
TEXT |
Owner's user ID |
code |
TEXT (UNIQUE) |
SHA-256 hashed recovery code |
used |
BOOLEAN |
Whether code has been used |
created_at |
TIMESTAMPTZ |
Creation timestamp |