SECURITY.md
Rama main · réplica de lectura del repositorio original.
# Security Policy
## Reporting a vulnerability
Please **don't** open a public issue for a security problem.
Report it privately through GitHub:
[Report a vulnerability](https://github.com/trylinky/linky/security/advisories/new).
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.