Reviewed-on: #1
HARDFILES
No logs. No tracking. No analytics. No weird anime girls on the homepage.
Upload a file, get a link, it's shredded in 24 hours.
Features
- Drag-and-drop, clipboard paste, file picker, and curl uploads
- Optional password protection on files
- 7-pass secure file shredding on expiry
- Random GIF backgrounds from a configurable directory
- IP-based rate limiting
- Streaming uploads (no memory buffering — handles files up to 5GB)
- Single Go binary, no database
Quick Start
go build -o hardfiles main.go
./hardfiles
Or with Docker:
docker compose up -d
Configuration
Edit config.toml:
webroot = "www"
lport = "5000"
vhost = "hardfiles.org"
filelen = 6
folder = "files"
bgfolder = "backgrounds"
max_upload_mb = 5120
ttl_hours = 24
rate_limit_per_min = 30
Usage
Browser
Visit the site, drop a file, get a link.
curl
# Upload a file
curl -F file=@photo.png https://hardfiles.org/
# Upload with password
curl -F file=@secret.pdf -F password=hunter2 https://hardfiles.org/
Bash Alias
# Add to ~/.bashrc
upload() {
curl -F file=@$1 https://hardfiles.org/
}
Then just upload /path/to/file.jpg.
Backgrounds
Add .gif files to the backgrounds/ directory. Each page load picks one at random. The more chaotic, the better.
Nginx Reverse Proxy
Hardfiles is designed to run behind nginx. Key configuration for large file uploads:
server {
listen 443 ssl;
server_name hardfiles.org;
# CRITICAL: Must match or exceed max_upload_mb in config.toml
client_max_body_size 5120m;
# Disable request buffering — stream directly to backend
proxy_request_buffering off;
# Increase timeouts for large uploads
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
# Increase header buffer for large multipart boundaries
proxy_buffer_size 16k;
proxy_buffers 4 32k;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
ssl_certificate /etc/letsencrypt/live/hardfiles.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hardfiles.org/privkey.pem;
}
Important nginx settings:
client_max_body_size 5120m— must matchmax_upload_mbin config.toml, or nginx will reject uploads before they reach hardfilesproxy_request_buffering off— prevents nginx from buffering the upload to disk before forwarding (critical for memory-limited servers)proxy_read_timeout 3600s— 1 hour timeout for large uploads on slow connections
Docker
# Build and run
docker compose up -d
# Volumes mounted:
# ./files:/app/files — uploaded files (auto-cleared every 24h)
# ./backgrounds:/app/backgrounds — GIF backgrounds
# ./config.toml:/app/config.toml — configuration
Security
- Files are shredded with 7-pass random overwrite before deletion (effective on HDD; ceremonial on SSD — use dm-crypt/LUKS for SSD)
- Path traversal prevention on all routes
- Upload size limits enforced at the HTTP level
- Password-protected files use bcrypt hashing
- MIME type allowlist for inline serving (images, PDFs, text, audio, video) — HTML/SVG/JS forced to download to prevent stored XSS
- Content-Security-Policy headers on all HTML responses
- No file listing or directory browsing
Credits
- delorean for developing hardfiles
- hgw for branding the product
- acidvegas for funding the project
License
MIT
Description
Languages
Go
77.6%
HTML
21.8%
Dockerfile
0.6%