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.
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.
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 plusAPP_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; seereencryptinapps/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.
getIpAddressprefers Cloudflare'sCF-Connecting-IPand otherwise takes the nearestX-Forwarded-Forhop. 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.