Skip to main content
Wwr.fi

Security

How wr.fi protects your data.

Honest status: wr.fi is a solo project, weeks old not years old. We've found and fixed 12 bugs through external security reviews from four AI models. The developer tools (CLI, MCP server) are open source (MIT) — audit every line at github.com/wrfi. But treat wr.fi like a public whiteboard, not a vault. Don't store secrets, credentials, or sensitive personal data here.

We'd rather be honest about where we are than pretend to be something we're not. Report issues at security@wr.fi.

Infrastructure

HostingAWS Lightsail (eu-central-1 — Frankfurt)
DNS / CDNCloudflare (configuration varies — may be proxied or DNS-only depending on operational needs)
TLSHTTPS everywhere. Certificate issued by Cloudflare or Let's Encrypt depending on proxy mode.
DatabaseSQLite (single file, encrypted at rest via EBS)
File storageContent-addressed (SHA-256 dedup), local filesystem with EBS encryption
Reverse proxyCaddy with HSTS
ApplicationNext.js 16 in Docker (node:20-slim)

What we store

  • Creations: title, content type, artifacts (files), metadata (provenance, generation info, tags)
  • Artifacts: stored by SHA-256 content hash — automatic deduplication, no filename-based storage
  • Accounts: username, bcrypt-hashed password, optional email (for notifications only)
  • Sessions: random token, 30-day expiry, invalidated on password change
  • Analytics: server-side event log (type, shortId, IP, user agent). No client-side tracking pixels.

What we don't store

  • No tracking pixels, no ad cookies, no third-party analytics scripts
  • No payment data (payment integration planned, not yet implemented)
  • No browsing history beyond server access logs
  • IP addresses: stored in server-side event logs for abuse prevention. Rate limit data is in-memory only and pruned every 24 hours.

Access model

TierVisibilityAuth to view
PublicIn feed, indexedNone
UnlistedNot in feed, not indexedNone — URL only (~1.2M combinations)
Secret link8-char URL, not in search or exploreNone — URL only (~2.8T combinations)
Password-protectedNot in feedPassword, view key, or edit token

Unlisted ≠ private. 4-char IDs have ~1.2M combinations. At the rate limit of 300 reads/min, a single IP could enumerate the full space in ~67 hours. Unlisted means “not advertised”, not “protected.” For sensitive content, use 8-char secret links (~2.8T combinations) or password protection.

Edit tokens have ~4M combinations (2 words from a 2048-word dictionary). Combined with rate limiting (5 attempts per creation per hour, 50 total per IP per hour), brute-force takes ~95 years per token.

Security headers

  • Content-Security-Policy (CSP) on all pages
  • Strict-Transport-Security (HSTS)
  • X-Frame-Options: DENY (except /embed/* which allows framing)
  • X-Content-Type-Options: nosniff
  • Permissions-Policy: restricted
  • SameSite=Lax on all cookies, HttpOnly, Secure in production
  • CORS: * only on public push/read endpoints. Sensitive endpoints are same-origin only.

Rate limiting

  • Anonymous pushes: 60/hour per IP
  • Login attempts: 20/hour per IP
  • Edit token failures: 5/shortId/hour
  • ShortId reads: 60/minute per IP (enumeration protection)
  • API key regeneration: 3/hour per account

Jurisdiction

wr.fi is operated by Kurikkai Oy, a Finnish company. Finnish jurisdiction means EU/GDPR by default, no FISA or CLOUD Act exposure. Data is processed in the EU (AWS eu-central-1, Frankfurt).

Open components

The developer tools are open source under MIT at github.com/wrfi:

  • CLI (npx wrfi) — MIT
  • MCP server (npx wrfi mcp) — MIT
  • WRFI specification — CC-BY-4.0

The wr.fi server is proprietary. We publish our security practices on this page and respond to vulnerability reports within 48 hours.

Responsible disclosure

Found a vulnerability? Email security@wr.fi. We respond within 48 hours and credit responsible disclosures. See also security.txt.