Skip to content

Security: trylinky/linky

Security

SECURITY.md

Security Policy

Reporting a vulnerability

Please don't open a public issue for a security problem.

Report it privately through GitHub: Report a vulnerability. That opens a private advisory visible only to the maintainers.

Useful things to include, as far as you have them:

  • what an attacker can do, and what they need in order to do it
  • the affected endpoint, page or package
  • steps to reproduce, or a proof of concept
  • whether it affects lin.ky, self-hosted instances, or both

You should get an acknowledgement within a few days. Please give us a reasonable window to ship a fix before disclosing publicly.

Supported versions

Linky is developed on main and the hosted version at lin.ky tracks it. Fixes land on main; there are no long-lived release branches to back-port to.

Notes for self-hosted deployments

A few settings are security-relevant and easy to miss:

  • TRUSTED_ORIGINS — the origins allowed to make credentialed (cookie-bearing) requests to the API. Set this to your own domains. If it is unset, the API falls back to the hosted lin.ky origins plus APP_FRONTEND_URL. Pages on user custom domains do not need to be listed: they only call session-free public endpoints.
  • ENCRYPTION_KEY — encrypts stored integration credentials. Treat it like a database password. Rotating it requires re-encrypting existing rows; see reencrypt in apps/api/src/lib/encrypt.ts.
  • INTERNAL_API_KEY — shared secret between the frontend and the API for internal endpoints. Anyone holding it can read unpublished page data.
  • Run the API behind a proxy that sets a trustworthy client IP. Form submission rate limiting and per-visitor reaction caps are keyed on it. getIpAddress prefers Cloudflare's CF-Connecting-IP and otherwise takes the nearest X-Forwarded-For hop. If your origin is reachable directly, bypassing the proxy, a client can set those headers itself and sidestep both limits — restrict the origin to your proxy.
  • Stripe webhooks are verified against STRIPE_WEBHOOK_SECRET. Don't disable that check.

There aren't any published security advisories