TREK Collab link-preview server-side request forgery via attacker-controlled URL without trip membership check
Summary
TREK v3.4.1 link-preview endpoint skips trip membership validation and lets the server fetch attacker-controlled URLs as an open proxy.
Details
CollabController.linkPreview (collab.controller.ts:281-299) discards user and tripId before passing the attacker url to fetchLinkPreview (collabService.ts:404-451), which fetch()es it (line 418) and relays og metadata, forming an SSRF/open proxy.
Core vulnerable code path:
// server/src/nest/collab/collab.controller.ts:281-299
@Get('link-preview')
async linkPreview(@CurrentUser() user: User, @Param('tripId') tripId: string, @Query('url') url?: string) {
// NB: the legacy route does not verify trip access on link-preview; kept 1:1.
void user; void tripId;
if (!url) {
throw new HttpException({ error: 'URL is required' }, 400);
}
try {
const preview = await this.collab.linkPreview(url);
Entry point: no trip membership check (void user; void tripId), no host allowlist; attacker-controlled URL enters server-side outbound request path.
// server/src/services/collabService.ts:404-423
export async function fetchLinkPreview(url: string): Promise<LinkPreviewResult> {
const parsed = new URL(url);
const ssrf = await checkSsrf(url, true);
if (!ssrf.allowed) {
return { ...fallback, error: ssrf.error } as LinkPreviewResult & { error?: string };
}
try {
const r = await fetch(url, {
redirect: 'error',
dispatcher: createPinnedDispatcher(ssrf.resolvedIp!),
} as any);
Sink: checkSsrf only blocks private/loopback/link-local IPs; public targets pass; fetch executes attacker URL and og metadata is relayed back -> open proxy/SSRF.
POC
Preconditions: any valid TREK account; target is a public service trusting server outbound IP or attacker-controlled probe. PoC: 1. POST /api/auth/login {email,password} -> trek_session cookie. 2. GET /api/trips/1/collab/link-preview?url=https%3A%2F%2Fattacker.example.com%2Fprobe (any tripId). 3. Server requests target from its outbound IP; response relays og:title/og:description/og:image.
Impact
Any registered user uses TREK server as open HTTP proxy to arbitrary public URLs. Main impact: confidentiality of server-reachable resource states/metadata.
Remediation
Add trip membership check (requireTrip + canEdit); use explicit domain allowlist; restrict protocol/size/timeout and re-validate redirects; add rate limiting; regression tests.
Disclosure Notes
Candidate finding (needs_verification). collab.controller.ts:281-299 skips trip membership checks; collabService.ts:404-451 fetches attacker URL and relays og metadata. Default config: public open proxy; internal reachability needs dynamic verification. No vendor-confirmed fix; affected version v3.4.1.
Supplemental Information
Affected products
- Ecosystem: self-hosted
- Package name: liketrek/TREK
- Affected versions: v3.4.1 (to be confirmed)
- Patched versions: to be confirmed
Severity
- Scoring method: CVSS v3.1
- Score: 7.1
- Vector string: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N
Weaknesses
- CWE: CWE-918 Server-Side Request Forgery (SSRF)
TREK Collab link-preview server-side request forgery via attacker-controlled URL without trip membership check
Summary
TREK v3.4.1 link-preview endpoint skips trip membership validation and lets the server fetch attacker-controlled URLs as an open proxy.
Details
CollabController.linkPreview (collab.controller.ts:281-299) discards user and tripId before passing the attacker url to fetchLinkPreview (collabService.ts:404-451), which fetch()es it (line 418) and relays og metadata, forming an SSRF/open proxy.
Core vulnerable code path:
Entry point: no trip membership check (void user; void tripId), no host allowlist; attacker-controlled URL enters server-side outbound request path.
Sink: checkSsrf only blocks private/loopback/link-local IPs; public targets pass; fetch executes attacker URL and og metadata is relayed back -> open proxy/SSRF.
POC
Preconditions: any valid TREK account; target is a public service trusting server outbound IP or attacker-controlled probe. PoC: 1. POST /api/auth/login {email,password} -> trek_session cookie. 2. GET /api/trips/1/collab/link-preview?url=https%3A%2F%2Fattacker.example.com%2Fprobe (any tripId). 3. Server requests target from its outbound IP; response relays og:title/og:description/og:image.
Impact
Any registered user uses TREK server as open HTTP proxy to arbitrary public URLs. Main impact: confidentiality of server-reachable resource states/metadata.
Remediation
Add trip membership check (requireTrip + canEdit); use explicit domain allowlist; restrict protocol/size/timeout and re-validate redirects; add rate limiting; regression tests.
Disclosure Notes
Candidate finding (needs_verification). collab.controller.ts:281-299 skips trip membership checks; collabService.ts:404-451 fetches attacker URL and relays og metadata. Default config: public open proxy; internal reachability needs dynamic verification. No vendor-confirmed fix; affected version v3.4.1.
Supplemental Information
Affected products
Severity
Weaknesses