BREAKING: CVE-2026-9317 lets anyone who can reach your Nango runner run code

BREAKING: CVE-2026-9317 lets anyone who can reach your Nango runner run code

How to fix CVE-2026-9317: upgrade nango to 0.71.6 and set NANGO_INTERNAL_AUTH_REQUIRED=true

2 min read466 words
Contents

Anyone who can reach your Nango runner port can start caller-supplied JavaScript in that process. Before 0.71.6, the runner tRPC surface exposed start, abort, and notifyWhenIdle as public procedures with an empty context. No auth middleware sat in front. Network access to the runner was enough to call start with caller-supplied code and execute it inside the runner.

Upgrade alone is not the fix. v0.71.6 ships runner auth, but NANGO_INTERNAL_AUTH_REQUIRED defaults to false. Shipping the new image with no new vars is a no-op. Existing runners keep accepting unauthenticated dispatch until you set REQUIRED=true and restart so runners inherit it.

What breaks

CVE-2026-9317 (VulnCheck, critical, CVSS 9.2 CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N, CWE-306) covers Nango >=0 <0.71.6. Fixed in 0.71.6 (GitHub release 2026-09-02). Credit: Katriel Moses, VulnCheck.

Pre-patch packages/runner/lib/server.ts registered those procedures as publicProcedure with empty createContext. RUNNER_SECRET_KEY existed in the env schema but was unenforced on this surface. PR #7288 / commit ed3030a9a0f8e4f3810fd10cb3a1905a2f5f87d2 (merged 2026-09-01) adds internalServiceAuthMiddleware plus task/node-bound procedures. Jobs mint an EdDSA JWT (aud: runner); runners verify with the public key only. /health stays open.

Docs and .env.example still default NANGO_INTERNAL_AUTH_REQUIRED to false. Fail-open is intentional until you flip the flag. Put the signing key on jobs only (NANGO_INTERNAL_AUTH_SIGNING_KEY). Set NANGO_INTERNAL_AUTH_REQUIRED=true on the orchestrator then jobs. Runners receive the public key and REQUIRED at node start. Never put the signing key on runners.

Who is not in scope

  • Nango Cloud customers (Nango operates the runners).
  • Deployments where the runner port is not reachable from untrusted hosts.
  • Callers that only hit GET /health.
  • Dashboard and public API login paths. This is runner-internal tRPC, not end-user auth.

How to check

From the deploy root, search compose/values/env for NANGO_INTERNAL_AUTH_REQUIRED and the nango image tag, then check runner /health and the installed nango package version.

Confirm image or package version is at least 0.71.6 and NANGO_INTERNAL_AUTH_REQUIRED=true on jobs, orchestrator, and runners after restart. An upgraded tag with REQUIRED still false or unset is still exposed on a reachable runner port.

How to fix

1. Upgrade self-hosted Nango to 0.71.6 or newer.

2. On jobs, set NANGO_INTERNAL_AUTH_SIGNING_KEY. Do not put that key on runners.

3. Set NANGO_INTERNAL_AUTH_REQUIRED=true on the orchestrator, then on jobs. Restart so runners inherit the public key and REQUIRED=true at node start.

4. Re-check version and REQUIRED after restart. Until REQUIRED=true is live on the runner processes, the open door remains.

What this is not

This is not a wormable internet bug without a path to the runner port. It is not fixed by an image bump alone without flipping REQUIRED. It is not the separate August 26 Nango proxy advisories.

References

Continue reading

All posts