Conversation
…om sessions Sessions were being invalidated whenever a visitor's IP address changed, which happens frequently with VPNs, mobile networks, and carrier-grade NAT. This caused visitors to be logged out after 1-2 minutes and forced re-verification via OTP. Changes: - dataroom-auth.ts: Add browser fingerprint (SHA-256 of User-Agent + Accept-Language) as the primary session binding factor. IP address is still stored for analytics/watermarking but no longer used for session validation. Legacy sessions without a fingerprint fall back to IP check for a smooth rollout. - link-session.ts: Remove IP address validation since User-Agent is already validated and provides the same device-binding guarantee without breaking on IP changes. - All createDataroomSession callers updated to pass the fingerprint. Security model: - Session tokens remain cryptographically strong (32/48 random bytes) - Cookies are httpOnly + sameSite preventing XSS/CSRF extraction - Browser fingerprint (UA + Accept-Language) prevents session sharing across different devices/browsers - IP is retained in session data for audit/watermarking purposes Co-authored-by: Marc Seitz <mfts@users.noreply.github.com>
Strengthens the browser fingerprint by including Sec-CH-UA, Sec-CH-UA-Platform, and Sec-CH-UA-Mobile headers in the hash. These client hints: - Include exact browser brand + version (harder to guess than User-Agent alone) - Are automatically sent by Chromium-based browsers - Require explicit effort to spoof (not captured by cookie-copy tools) Also refactors fingerprint collection into a shared collectFingerprintHeaders() helper to avoid duplicating header extraction logic across callers. Co-authored-by: Marc Seitz <mfts@users.noreply.github.com>
|
Cursor Agent can help with this pull request. Just |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughIntroduces fingerprint-based session handling for dataroom sessions by adding functions to generate session fingerprints from request headers (User-Agent, Accept-Language, Sec-CH-UA), updating dataroom session creation to accept and store fingerprints, and modifying multiple API routes to compute and pass fingerprints during session creation. Also removes IP address verification from link session validation. Changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/auth/link-session.ts (1)
106-111:⚠️ Potential issue | 🟠 MajorDon’t rely on
user-agentalone for link-session validation.This removes the IP check without replacing it with the new fingerprint that dataroom sessions now use. A copied
pm_ls_*cookie from another machine on the same browser/version will still pass this check, so protected link sessions get materially easier to replay. Please persist and compare a fingerprint here as well.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/auth/link-session.ts` around lines 106 - 111, The current check only compares currentUserAgent vs sessionData.userAgent, which allows cookie replay across machines with the same UA; modify this link-session validation to also compare a stored fingerprint: compute a fingerprint from the incoming request (e.g., client IP from X-Forwarded-For or connection, relevant headers and user-agent) and compare it to sessionData.fingerprint, and if they differ call deleteLinkSession(sessionToken, sessionData.viewerId) and return null; ensure when creating the session you persist that same fingerprint into sessionData.fingerprint (update the session creation code path that writes link-session records) so the stored fingerprint and this comparison use the identical fingerprinting function/logic.
🧹 Nitpick comments (1)
lib/auth/dataroom-auth.ts (1)
71-83: Keep request-to-fingerprint derivation behind one shared helper.
getFingerprintFromPagesRequestandgetFingerprintFromNextRequestalready define the auth-relevant header projection, butpages/api/links/download/verify.tsLines 190-196 still recreate the pages-router adapter inline. I’d reuse a single request-level helper for session creation too so future header tweaks can’t make creation and verification drift apart.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/auth/dataroom-auth.ts` around lines 71 - 83, The two existing helpers getFingerprintFromNextRequest and getFingerprintFromPagesRequest both project the same auth headers and call collectFingerprintHeaders + generateSessionFingerprint; extract that logic into a single shared helper (e.g., getFingerprintFromRequest or normalizeRequestFingerprint) that accepts a headers-like accessor (object with get(name): string | null) or a NextRequest/NextApiRequest and returns the fingerprint via collectFingerprintHeaders + generateSessionFingerprint, then update getFingerprintFromNextRequest and getFingerprintFromPagesRequest to delegate to that new helper and replace the inline pages-router adapter in pages/api/links/download/verify.ts with a call to the new helper so header projection is centralized and cannot drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@lib/auth/link-session.ts`:
- Around line 106-111: The current check only compares currentUserAgent vs
sessionData.userAgent, which allows cookie replay across machines with the same
UA; modify this link-session validation to also compare a stored fingerprint:
compute a fingerprint from the incoming request (e.g., client IP from
X-Forwarded-For or connection, relevant headers and user-agent) and compare it
to sessionData.fingerprint, and if they differ call
deleteLinkSession(sessionToken, sessionData.viewerId) and return null; ensure
when creating the session you persist that same fingerprint into
sessionData.fingerprint (update the session creation code path that writes
link-session records) so the stored fingerprint and this comparison use the
identical fingerprinting function/logic.
---
Nitpick comments:
In `@lib/auth/dataroom-auth.ts`:
- Around line 71-83: The two existing helpers getFingerprintFromNextRequest and
getFingerprintFromPagesRequest both project the same auth headers and call
collectFingerprintHeaders + generateSessionFingerprint; extract that logic into
a single shared helper (e.g., getFingerprintFromRequest or
normalizeRequestFingerprint) that accepts a headers-like accessor (object with
get(name): string | null) or a NextRequest/NextApiRequest and returns the
fingerprint via collectFingerprintHeaders + generateSessionFingerprint, then
update getFingerprintFromNextRequest and getFingerprintFromPagesRequest to
delegate to that new helper and replace the inline pages-router adapter in
pages/api/links/download/verify.ts with a call to the new helper so header
projection is centralized and cannot drift.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c5666467-e9f0-4300-84be-9747ed640b5c
📒 Files selected for processing (6)
app/(ee)/api/workflow-entry/domains/[...domainSlug]/route.tsapp/(ee)/api/workflow-entry/link/[entryLinkId]/access/route.tsapp/api/views-dataroom/route.tslib/auth/dataroom-auth.tslib/auth/link-session.tspages/api/links/download/verify.ts
Replaced strict IP-based session validation with an enriched browser fingerprint and removed IP validation from link sessions to prevent frequent logouts for users with dynamic IPs.
Previously, dataroom sessions were invalidated if the user's IP address changed, leading to frequent re-verification for users on VPNs or mobile networks. This change uses a more stable browser fingerprint (User-Agent, Accept-Language, Sec-CH-UA headers) to bind sessions to a device, improving user experience without compromising security. IP addresses are still stored for analytics.
Summary by CodeRabbit
New Features
Bug Fixes
Improvements