Skip to content

Fixes CSP for Nango#2907

Merged
robert-inkeep merged 1 commit intomainfrom
fix-csp
Mar 30, 2026
Merged

Fixes CSP for Nango#2907
robert-inkeep merged 1 commit intomainfrom
fix-csp

Conversation

@robert-inkeep
Copy link
Copy Markdown
Collaborator

No description provided.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 30, 2026

⚠️ No Changeset found

Latest commit: 6f6c7ab

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agents-api Ready Ready Preview, Comment Mar 30, 2026 8:09pm
agents-manage-ui Ready Ready Preview, Comment Mar 30, 2026 8:09pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
agents-docs Skipped Skipped Mar 30, 2026 8:09pm

Request Review

@pullfrog
Copy link
Copy Markdown
Contributor

pullfrog Bot commented Mar 30, 2026

TL;DR — Nango uses WebSocket connections at runtime, but the Content Security Policy's connect-src directive only allowed the HTTPS origin. This adds the corresponding wss:// origin so the browser no longer blocks Nango's WebSocket traffic.

Key changes

  • Add toWebSocketOrigin helper and include wss:// Nango origin in CSP — Converts an HTTP(S) URL to its ws:///wss:// equivalent so the CSP connect-src directive permits WebSocket connections to the Nango server.

Summary | 1 file | 1 commit | base: mainfix-csp

Before: CSP connect-src included only the HTTPS origin for PUBLIC_NANGO_SERVER_URL, causing the browser to block WebSocket (wss://) connections Nango initiates at runtime.
After: A new toWebSocketOrigin helper derives the wss:// (or ws://) origin from the configured Nango URL and appends it to connect-src, allowing both HTTPS and WebSocket traffic.

The helper is defensive — it returns null for missing, unparseable, or non-HTTP(S) inputs, so it slots cleanly into the existing .filter(Boolean) chain.

agents-manage-ui/src/proxy.ts

Pullfrog  | View workflow run | Triggered by Pullfrog | Using Claude Opus𝕏

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

Clean, correct fix. toWebSocketOrigin properly maps https:wss: and http:ws: using URL constructor, handles null/invalid inputs gracefully, and URL.origin returns the expected value for WebSocket protocols. No issues found.

Pullfrog  | View workflow run | Using Claude Opus𝕏

Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low

This PR adds WebSocket protocol support to the CSP (Content Security Policy) for Nango connections. The change is minimal, well-implemented, and follows existing patterns in the codebase.

What Changed

A new helper function toWebSocketOrigin() converts HTTP/HTTPS URLs to their WebSocket equivalents (WS/WSS), which is then used to add the Nango server's WebSocket origin to the CSP connect-src directive. This allows WebSocket connections to Nango to pass CSP validation.

Review Coverage

Reviewer Returned Main Findings Consider Discarded
pr-review-standards 0 0 0 0
pr-review-appsec 0 0 0 0
Total 0 0 0 0

Analysis

Code Quality

  • The toWebSocketOrigin function is well-implemented with proper null/undefined handling
  • Uses URL constructor for safe parsing with appropriate try/catch
  • Returns .origin (not full URL) which is correct for CSP sources
  • Only converts known protocols (http → ws, https → wss)

Security

  • CSP modification is secure — values come from environment variables, not user input
  • Follows existing patterns for other CSP sources in the file
  • Fail-safe behavior (returns null on errors, which is filtered out)

Consistency

  • Follows existing helper function patterns in the file
  • Uses the same filter(Boolean) pattern for CSP array construction

✅ APPROVE

Summary: Clean, minimal fix that correctly adds WebSocket origin support for Nango to the CSP. The implementation is secure, well-tested against edge cases, and follows existing codebase patterns. Ship it! 🚀

@github-actions github-actions Bot deleted a comment from claude Bot Mar 30, 2026
@robert-inkeep robert-inkeep enabled auto-merge March 30, 2026 20:09
@robert-inkeep robert-inkeep added this pull request to the merge queue Mar 30, 2026
Merged via the queue into main with commit b5bd269 Mar 30, 2026
22 checks passed
@robert-inkeep robert-inkeep deleted the fix-csp branch March 30, 2026 20:25
@itoqa
Copy link
Copy Markdown

itoqa Bot commented Mar 30, 2026

Ito Test Report ✅

12 test cases ran. 12 passed.

All 12 test cases passed, confirming expected behavior across auth boundaries, CSP/security headers, provider navigation/setup resilience, mobile usability, adversarial security checks, and OAuth callback handling in non-cloud mode. Key findings were that protected and public routes (including 307 redirects) consistently carried required CSP/X-Frame-Options/X-Content-Type-Options headers with Nango HTTP and WebSocket origins, unauthenticated deep-links correctly redirected to /login with returnUrl preservation, invalid provider links safely recovered without crashes while back/forward/refresh and rapid-click stress remained responsive, websocket egress to ws://evil.invalid/ws was blocked by CSP, and /oauth/callback could not be coerced into an open redirect (returning 404 JSON with no Location), with provider-flow checks executed via deterministic local fallback when Nango was unavailable.

✅ Passed (12)
Category Summary Screenshot
Adversarial Unauthenticated deep-link redirected to /login with preserved returnUrl, and login response retained required security headers. ADV-1
Adversarial Adversarial callback params (redirect_uri/next) did not coerce redirect destination and still returned 404 JSON. ADV-2
Adversarial Rapid repeated setup clicks kept a single-tab flow and the page stayed responsive in the local provider fallback path. ADV-3
Adversarial Adversarial WebSocket to ws://evil.invalid/ws triggered a CSP violation and never reached open state. ADV-4
Edge Project base route returned HTTP 307 to /agents?from=test and retained CSP, X-Frame-Options, and X-Content-Type-Options. EDGE-1
Edge /login returned CSP header with connect-src containing both Nango HTTP origin (http://localhost:3050) and converted WS origin (ws://localhost:3050), and the login page remained interactive with no fatal rendering breakage. EDGE-2
Edge Invalid provider deep-link showed a safe not-found state with a working recovery path and no crash state. EDGE-3
Edge Back/forward/refresh stress on provider setup kept the page interactive and recoverable. EDGE-4
Mobile At 390x844, providers grid and provider setup views remained visible, tappable, and free of horizontal overflow. MOBILE-1
Happy-path Protected providers-route CSP included self plus Nango HTTP and WebSocket origins, with expected auth-boundary headers preserved. ROUTE-1
Happy-path Provider grid, valid provider detail, invalid deep-link recovery, and mobile navigation remained functional under the tested setup. ROUTE-2
Happy-path Non-cloud /oauth/callback smoke and adversarial requests returned expected 404 JSON with no redirect location. ROUTE-4

Commit: 6f6c7ab

View Full Run


Tell us how we did: Give Ito Feedback

tim-inkeep pushed a commit that referenced this pull request Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant