Skip to content

fix(server): trust proxy and trusted client IP for redirect and attribution#10

Merged
onamfc merged 1 commit intoLinkForty:mainfrom
RaoUsama7:fix/trust-proxy-client-ip
Mar 16, 2026
Merged

fix(server): trust proxy and trusted client IP for redirect and attribution#10
onamfc merged 1 commit intoLinkForty:mainfrom
RaoUsama7:fix/trust-proxy-client-ip

Conversation

@RaoUsama7
Copy link
Contributor

Description

Harden production use when the app runs behind reverse proxies, CDNs, or load balancers. The platform relies on client IP for redirect targeting, attribution confidence, and fingerprint matching. Without trust proxy, request.ip can be the proxy IP; and the SDK install endpoint previously trusted client-provided ipAddress in the body, which is spoofable. This change adds configurable proxy trust, a single helper for trusted client IP, and ensures client body IP is never used for trust.

Type of Change

  • Bug fix (production hardening / security-related)
  • New feature
  • Breaking change
  • Documentation update

Changes Made

  • Fastify: Add trustProxy to ServerOptions and pass it into Fastify() so request.ip can be taken from X-Forwarded-For when behind a proxy.
  • Helper: Add getClientIp(request) in src/lib/client-ip.ts (with IPv6-mapped unwrap and fallback to socket.remoteAddress or 'unknown').
  • Redirect routes: Use getClientIp(request) for targeting and click tracking instead of request.ip.
  • SDK install: Use only getClientIp(request) for attribution/fingerprint; keep optional body.ipAddress as debug-only and return it as clientReportedIp when present.
  • SDK resolve: Use getClientIp(request) for click recording.
  • Config: Add TRUST_PROXY env support in .env.example and examples/basic-server.ts (e.g. TRUST_PROXY=1 or hop count).
  • Tests: Add src/lib/client-ip.test.ts (getClientIp unit tests, proxied request with trustProxy, SDK install spoof test asserting body IP is not trusted).
  • Docs: README "Running behind a reverse proxy" and CONTRIBUTING note on TRUST_PROXY and that client ipAddress is not trusted.

Testing

  • npm run build — succeeds.
  • npm run test — all 27 tests pass, including 7 new client-ip tests (direct IP, socket fallback, IPv6-mapped, unknown, trustProxy + X-Forwarded-For, SDK install spoof).
  • No new lint issues.

Related Issues

N/A (production hardening as requested; no issue number).

…ening for deployments behind reverse proxies, CDNs, and load balancers.Changes:- Add configurable Fastify trustProxy support via ServerOptions and TRUST_PROXY env- Introduce getClientIp() helper for consistent client IP extraction- Update redirect and SDK routes to rely on trusted server-derived IP- Prevent spoofed client-provided ipAddress from being used for attribution- Add unit tests for proxy scenarios and spoofed SDK install requests- Document proxy behavior and TRUST_PROXY configuration
@CLAassistant
Copy link

CLAassistant commented Mar 10, 2026

CLA assistant check
All committers have signed the CLA.

@onamfc onamfc self-requested a review March 15, 2026 17:23
Copy link
Member

@onamfc onamfc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great contribution — this is a meaningful security hardening. The core fix (no longer trusting client-provided body.ipAddress for attribution) is exactly right, and the getClientIp helper is clean and well-tested.

A couple minor suggestions for future consideration (not blocking merge):

  1. Type safety on socket fallback(request as any).socket?.remoteAddress could be request.raw.socket?.remoteAddress to avoid the as any cast and use Fastify's typed IncomingMessage.

  2. 'unknown' fallback — Worth noting that 'unknown' is truthy and flows through normalizeIP unchanged, which means two installs with no IP would match on the IP fingerprint factor (40 points). Not introduced by this PR, but something to be aware of. An empty string would be safer since normalizeIP already returns '' for falsy inputs.

Tests are solid — the spoof prevention test is exactly the kind of coverage this change needs. Merging!

@onamfc onamfc merged commit de12521 into LinkForty:main Mar 16, 2026
1 of 2 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Mar 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants