{"id":"CVE-2026-54673","aliases":["EUVD-2026-40455","GHSA-p2f4-r6v6-j797","openSUSE-SU-2026:11200-1"],"status":"published","title":"electron-updater: Cross-origin redirect leaks `PRIVATE-TOKEN` and mixed-case `Authorization` credentials in `builder-util-runtime`","description":"electron-updater allows for automatic updates for Electron apps. Prior to 9.7.0, the HTTP redirect handler (HttpExecutor.prepareRedirectUrlOptions) only stripped a credential header whose key string matched exactly lowercase \"authorization\", exposing credentials. Other credential-bearing headers — most notably PRIVATE-TOKEN (used by GitLab's personal access token flow) and mixed-case Authorization (used by GitLab's Bearer/OAuth flow) — were not stripped and could be forwarded to an attacker-controlled cross-origin redirect destination. This issue has been fixed in version 9.7.0.","severity":{"version":"4.0","score":8.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00407,"percentile":0.3551,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-200"],"published":"2026-06-30T22:11:37Z","modified":"2026-10-28T02:31:06Z","fixes":[{"ecosystem":"npm","package":"builder-util-runtime","fixed_in":["9.7.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"builder-util-runtime","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"9.7.0"}]}]},{"source":"osv","ecosystem":"npm","package":"builder-util-runtime","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"9.7.0"}]}]},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"heroic-games-launcher","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.22.0-4.1"}]}],"bundled":3}],"products":[{"vendor":"electron","product":"builder-util-runtime"},{"vendor":"electron","product":"electron-builder"},{"vendor":"electron-userland","product":"builder-util-runtime"},{"vendor":"electron-userland","product":"electron-builder"}],"references":[{"url":"https://github.com/electron-userland/electron-builder/security/advisories/GHSA-p2f4-r6v6-j797","tags":["x_refsource_CONFIRM","exploit","Vendor Advisory","Exploit","Mitigation","Patch","advisory","web"]},{"url":"https://github.com/electron-userland/electron-builder/commit/22a7532bd01b9fb42cff7c58d599c7ad683569fe","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-54673","tags":["advisory"]},{"url":"https://github.com/electron-userland/electron-builder/pull/9834","tags":["web"]},{"url":"https://github.com/electron-userland/electron-builder/releases/tag/electron-builder@26.15.0","tags":["web"]},{"url":"https://github.com/advisories/GHSA-p2f4-r6v6-j797"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54673.json","tags":["advisory"]},{"url":"https://github.com/electron-userland/electron-builder","tags":["package"]},{"url":"","tags":["advisory"]},{"url":"https://www.suse.com/security/cve/CVE-2026-54672","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-54673","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-56876","tags":["web"]}],"sources":{"cve":[{"id":"CVE-2026-54673","title":"electron-updater: Cross-origin redirect leaks `PRIVATE-TOKEN` and mixed-case `Authorization` credentials in `builder-util-runtime`","description":"electron-updater allows for automatic updates for Electron apps. Prior to 9.7.0, the HTTP redirect handler (HttpExecutor.prepareRedirectUrlOptions) only stripped a credential header whose key string matched exactly lowercase \"authorization\", exposing credentials. Other credential-bearing headers — most notably PRIVATE-TOKEN (used by GitLab's personal access token flow) and mixed-case Authorization (used by GitLab's Bearer/OAuth flow) — were not stripped and could be forwarded to an attacker-controlled cross-origin redirect destination. This issue has been fixed in version 9.7.0.","status":"published","published":"2026-06-30T22:11:37.587Z","modified":"2026-07-01T13:26:49.397Z","cvss":[{"version":"4.0","score":8.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N","level":"high","assessor":"cna"}],"cwes":["CWE-200"],"updated_at":"2026-11-02T13:38:09.774038Z"}],"euvd":[{"id":"EUVD-2026-40455","description":"electron-updater allows for automatic updates for Electron apps. Prior to 9.7.0, the HTTP redirect handler (HttpExecutor.prepareRedirectUrlOptions) only stripped a credential header whose key string matched exactly lowercase \"authorization\", exposing credentials. Other credential-bearing headers — most notably PRIVATE-TOKEN (used by GitLab's personal access token flow) and mixed-case Authorization (used by GitLab's Bearer/OAuth flow) — were not stripped and could be forwarded to an attacker-controlled cross-origin redirect destination. This issue has been fixed in version 9.7.0.","status":"published","published":"2026-06-30T22:11:37Z","modified":"2026-07-01T13:26:49Z","cvss":[{"version":"4.0","score":8.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T18:20:20.297775Z"}],"ghsa":[{"id":"GHSA-p2f4-r6v6-j797","title":"electron-updater: Cross-origin redirect leaks `PRIVATE-TOKEN` and mixed-case `Authorization` credentials in `builder-util-runtime`","description":"## Summary\n\nIn `electron-builder`'s `builder-util-runtime` package, the HTTP redirect handler (`HttpExecutor.prepareRedirectUrlOptions`) only stripped a credential header whose key string matched exactly lowercase `\"authorization\"`. Other credential-bearing headers — most notably `PRIVATE-TOKEN` (used by GitLab's personal access token flow) and mixed-case `Authorization` (used by GitLab's Bearer/OAuth flow) — were not stripped and could be forwarded to an attacker-controlled cross-origin redirect destination.\n\n---\n\n## Details\n\n### Root cause\n\n`HttpExecutor.prepareRedirectUrlOptions` (introduced in `builder-util-runtime` via [PR #9211](https://github.com/electron-userland/electron-builder/pull/9211), first released in `v26.0.20`) performed its cross-origin credential strip with a single case-sensitive property check:\n\n```typescript\n// vulnerable code (electron-builder v26.0.20 – v26.14.x) [via builder-util-runtime \u003c9.7.0]\nif (headers?.authorization) {\n  if (HttpExecutor.isCrossOriginRedirect(originalUrl, parsedRedirectUrl)) {\n    delete headers.authorization   // only removes the exact key \"authorization\"\n  }\n}\n```\n\nJavaScript object property access is case-sensitive. The guard `headers?.authorization` evaluates to `undefined` (falsy) when the key is `\"Authorization\"`, `\"AUTHORIZATION\"`, or any other casing, so the branch is never entered and **no header is deleted** for those cases.\n\n### Affected updater flows\n\nThe clearest reproduced path is the private GitLab updater flow.\n\n`packages/electron-updater/src/providers/GitLabProvider.ts` sets one of two credential headers depending on the token type:\n\n```typescript\n// GitLabProvider.setAuthHeaderForToken (affected versions)\nif (token.startsWith(\"Bearer\")) {\n  headers.authorization = token        // Bearer / OAuth token  →  key is lowercase\n} else {\n  headers[\"PRIVATE-TOKEN\"] = token     // personal access token →  key is \"PRIVATE-TOKEN\"\n}\n```\n\nDuring a private release update check, the updater requests a release asset through GitLab's `direct_asset_url`. GitLab commonly redirects asset downloads to an external object-storage origin (e.g., S3, GCS). Because the redirect crosses origins:\n\n1. A personal access token in `PRIVATE-TOKEN` **is never inspected** by the vulnerable strip guard — it is forwarded intact.\n2. A Bearer token set as `headers.authorization` (lowercase) **is stripped** correctly.\n3. A Bearer token set as `headers.Authorization` (capital A) or any other mixed-case variant **bypasses the guard** and is forwarded intact.\n\nGitLab is the concrete reproduced case; any other provider or custom updater configuration that places credentials in a non-lowercase-`authorization` header is equally affected.\n\n### Before v26.0.20\n\nVersions prior to `v26.0.20` did not contain `prepareRedirectUrlOptions` at all. All credential headers were forwarded unchanged on every redirect, regardless of origin. This represents a broader, pre-existing version of the same class of vulnerability.\n\n---\n\n## Proof of concept (reproduction shape)\n\n1. Configure the updater with an authenticated GitLab provider, supplying a personal access token (non-Bearer). The provider will set `PRIVATE-TOKEN: \u003ctoken\u003e` on requests.\n2. Trigger an update check. The updater fetches release metadata and then requests a release asset URL.\n3. The trusted GitLab origin returns a 3xx cross-origin redirect (e.g., to S3 object storage).\n4. `HttpExecutor.prepareRedirectUrlOptions` is called. The guard `headers?.authorization` is falsy (the key is `\"PRIVATE-TOKEN\"`). No header is deleted.\n5. The request to the redirect destination is issued with `PRIVATE-TOKEN: \u003ctoken\u003e` present in the headers.\n\n**Observed result:** The personal access token is forwarded to the redirect destination. An attacker who controls or can observe the redirect destination receives the token.\n\n---\n\n## Impact\n\nThis is a credential disclosure vulnerability. An automatic update check can leak:\n\n- GitLab personal access tokens (`PRIVATE-TOKEN`)\n- Bearer/OAuth tokens sent under a mixed-case `Authorization` key\n- Any other credential header not named exactly `\"authorization\"` in lowercase\n\nDisclosure of a GitLab PAT grants the attacker whatever repository and API permissions the token carries, enabling unauthorized access to private source code, packages, or release artifacts.\n\n---\n\n## Patches\n\nFixed in electron-builder `v26.15.0` [included via `v9.7.0` `builder-util-runtime`] via [PR #9834](https://github.com/electron-userland/electron-builder/pull/9834) (commit [`22a7532bd`](https://github.com/electron-userland/electron-builder/commit/22a7532bd01b9fb42cff7c58d599c7ad683569fe)).\n\nThe incomplete property-access guard was replaced with a separator-agnostic, case-insensitive lookup against a registry of known sensitive header names:\n\n```typescript\n// fixed code (v9.7.0+)\nconst normalizeName = (name: string): string =\u003e\n  name.toLowerCase().replace(/[-_]/g, \"\")\n\nconst SENSITIVE_REDIRECT_HEADERS = new Set([\n  \"authorization\", \"proxyauthorization\", \"privatetoken\",\n  \"xapikey\", \"xauthtoken\", \"xaccesstoken\", \"xgitlabtoken\",\n  \"cookie\", \"xcsrftoken\",\n])\n\n// In prepareRedirectUrlOptions, on cross-origin redirect:\nfor (const key of Object.keys(headers)) {\n  if (SENSITIVE_REDIRECT_HEADERS.has(normalizeName(key))) {\n    delete (headers as Record\u003cstring, unknown\u003e)[key]\n  }\n}\n```\n\n`normalizeName` converts to lowercase and strips `-` and `_` separators, so `PRIVATE-TOKEN`, `Private-Token`, `Authorization`, `AUTHORIZATION`, `X-Api-Key`, etc. are all matched. The fix also exports `addSensitiveRedirectHeader()` to allow custom publishers to register additional headers.\n\n**Upgrade path:** Update `builder-util-runtime` to `\u003e= 9.7.0`.\n\n---\n\n## Workarounds\n\nThere is no configuration-level workaround that prevents header forwarding in affected versions. The only mitigation short of upgrading is to avoid authenticated GitLab updater flows on versions `\u003c 9.7.0`.\n\nIf operating in a network environment where you control all possible redirect destinations, you may be able to prevent the token from reaching an attacker-controlled host through network-layer controls, but this is not a reliable mitigation.","status":"published","published":"2026-07-24T14:03:19Z","modified":"2026-07-24T14:03:21Z","cvss":[{"version":"4.0","score":8.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N","level":"high"}],"cwes":["CWE-200"],"updated_at":"2026-11-02T14:40:52.46233Z"}],"nvd":[{"id":"CVE-2026-54673","description":"electron-updater allows for automatic updates for Electron apps. Prior to 9.7.0, the HTTP redirect handler (HttpExecutor.prepareRedirectUrlOptions) only stripped a credential header whose key string matched exactly lowercase \"authorization\", exposing credentials. Other credential-bearing headers — most notably PRIVATE-TOKEN (used by GitLab's personal access token flow) and mixed-case Authorization (used by GitLab's Bearer/OAuth flow) — were not stripped and could be forwarded to an attacker-controlled cross-origin redirect destination. This issue has been fixed in version 9.7.0.","status":"published","published":"2026-06-30T23:17:28Z","modified":"2026-08-26T19:13:27.07Z","cvss":[{"version":"4.0","score":8.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"high","assessor":"secondary"},{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"primary"}],"cwes":["CWE-200"],"updated_at":"2026-11-02T14:12:26.866638Z"}],"osv":[{"id":"CVE-2026-54673","title":"electron-updater: Cross-origin redirect leaks `PRIVATE-TOKEN` and mixed-case `Authorization` credentials in `builder-util-runtime`","description":"electron-updater allows for automatic updates for Electron apps. Prior to 9.7.0, the HTTP redirect handler (HttpExecutor.prepareRedirectUrlOptions) only stripped a credential header whose key string matched exactly lowercase \"authorization\", exposing credentials. Other credential-bearing headers — most notably PRIVATE-TOKEN (used by GitLab's personal access token flow) and mixed-case Authorization (used by GitLab's Bearer/OAuth flow) — were not stripped and could be forwarded to an attacker-controlled cross-origin redirect destination. This issue has been fixed in version 9.7.0.","status":"published","published":"2026-06-30T22:11:37.587Z","modified":"2026-11-11T10:31:12.853334794Z","cvss":[{"version":"4.0","score":8.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N","level":"high"}],"cwes":["CWE-200"],"updated_at":"2026-11-11T11:06:48.457425Z"},{"id":"GHSA-p2f4-r6v6-j797","title":"electron-updater: Cross-origin redirect leaks `PRIVATE-TOKEN` and mixed-case `Authorization` credentials in `builder-util-runtime`","description":"## Summary\n\nIn `electron-builder`'s `builder-util-runtime` package, the HTTP redirect handler (`HttpExecutor.prepareRedirectUrlOptions`) only stripped a credential header whose key string matched exactly lowercase `\"authorization\"`. Other credential-bearing headers — most notably `PRIVATE-TOKEN` (used by GitLab's personal access token flow) and mixed-case `Authorization` (used by GitLab's Bearer/OAuth flow) — were not stripped and could be forwarded to an attacker-controlled cross-origin redirect destination.\n\n---\n\n## Details\n\n### Root cause\n\n`HttpExecutor.prepareRedirectUrlOptions` (introduced in `builder-util-runtime` via [PR #9211](https://github.com/electron-userland/electron-builder/pull/9211), first released in `v26.0.20`) performed its cross-origin credential strip with a single case-sensitive property check:\n\n```typescript\n// vulnerable code (electron-builder v26.0.20 – v26.14.x) [via builder-util-runtime \u003c9.7.0]\nif (headers?.authorization) {\n  if (HttpExecutor.isCrossOriginRedirect(originalUrl, parsedRedirectUrl)) {\n    delete headers.authorization   // only removes the exact key \"authorization\"\n  }\n}\n```\n\nJavaScript object property access is case-sensitive. The guard `headers?.authorization` evaluates to `undefined` (falsy) when the key is `\"Authorization\"`, `\"AUTHORIZATION\"`, or any other casing, so the branch is never entered and **no header is deleted** for those cases.\n\n### Affected updater flows\n\nThe clearest reproduced path is the private GitLab updater flow.\n\n`packages/electron-updater/src/providers/GitLabProvider.ts` sets one of two credential headers depending on the token type:\n\n```typescript\n// GitLabProvider.setAuthHeaderForToken (affected versions)\nif (token.startsWith(\"Bearer\")) {\n  headers.authorization = token        // Bearer / OAuth token  →  key is lowercase\n} else {\n  headers[\"PRIVATE-TOKEN\"] = token     // personal access token →  key is \"PRIVATE-TOKEN\"\n}\n```\n\nDuring a private release update check, the updater requests a release asset through GitLab's `direct_asset_url`. GitLab commonly redirects asset downloads to an external object-storage origin (e.g., S3, GCS). Because the redirect crosses origins:\n\n1. A personal access token in `PRIVATE-TOKEN` **is never inspected** by the vulnerable strip guard — it is forwarded intact.\n2. A Bearer token set as `headers.authorization` (lowercase) **is stripped** correctly.\n3. A Bearer token set as `headers.Authorization` (capital A) or any other mixed-case variant **bypasses the guard** and is forwarded intact.\n\nGitLab is the concrete reproduced case; any other provider or custom updater configuration that places credentials in a non-lowercase-`authorization` header is equally affected.\n\n### Before v26.0.20\n\nVersions prior to `v26.0.20` did not contain `prepareRedirectUrlOptions` at all. All credential headers were forwarded unchanged on every redirect, regardless of origin. This represents a broader, pre-existing version of the same class of vulnerability.\n\n---\n\n## Proof of concept (reproduction shape)\n\n1. Configure the updater with an authenticated GitLab provider, supplying a personal access token (non-Bearer). The provider will set `PRIVATE-TOKEN: \u003ctoken\u003e` on requests.\n2. Trigger an update check. The updater fetches release metadata and then requests a release asset URL.\n3. The trusted GitLab origin returns a 3xx cross-origin redirect (e.g., to S3 object storage).\n4. `HttpExecutor.prepareRedirectUrlOptions` is called. The guard `headers?.authorization` is falsy (the key is `\"PRIVATE-TOKEN\"`). No header is deleted.\n5. The request to the redirect destination is issued with `PRIVATE-TOKEN: \u003ctoken\u003e` present in the headers.\n\n**Observed result:** The personal access token is forwarded to the redirect destination. An attacker who controls or can observe the redirect destination receives the token.\n\n---\n\n## Impact\n\nThis is a credential disclosure vulnerability. An automatic update check can leak:\n\n- GitLab personal access tokens (`PRIVATE-TOKEN`)\n- Bearer/OAuth tokens sent under a mixed-case `Authorization` key\n- Any other credential header not named exactly `\"authorization\"` in lowercase\n\nDisclosure of a GitLab PAT grants the attacker whatever repository and API permissions the token carries, enabling unauthorized access to private source code, packages, or release artifacts.\n\n---\n\n## Patches\n\nFixed in electron-builder `v26.15.0` [included via `v9.7.0` `builder-util-runtime`] via [PR #9834](https://github.com/electron-userland/electron-builder/pull/9834) (commit [`22a7532bd`](https://github.com/electron-userland/electron-builder/commit/22a7532bd01b9fb42cff7c58d599c7ad683569fe)).\n\nThe incomplete property-access guard was replaced with a separator-agnostic, case-insensitive lookup against a registry of known sensitive header names:\n\n```typescript\n// fixed code (v9.7.0+)\nconst normalizeName = (name: string): string =\u003e\n  name.toLowerCase().replace(/[-_]/g, \"\")\n\nconst SENSITIVE_REDIRECT_HEADERS = new Set([\n  \"authorization\", \"proxyauthorization\", \"privatetoken\",\n  \"xapikey\", \"xauthtoken\", \"xaccesstoken\", \"xgitlabtoken\",\n  \"cookie\", \"xcsrftoken\",\n])\n\n// In prepareRedirectUrlOptions, on cross-origin redirect:\nfor (const key of Object.keys(headers)) {\n  if (SENSITIVE_REDIRECT_HEADERS.has(normalizeName(key))) {\n    delete (headers as Record\u003cstring, unknown\u003e)[key]\n  }\n}\n```\n\n`normalizeName` converts to lowercase and strips `-` and `_` separators, so `PRIVATE-TOKEN`, `Private-Token`, `Authorization`, `AUTHORIZATION`, `X-Api-Key`, etc. are all matched. The fix also exports `addSensitiveRedirectHeader()` to allow custom publishers to register additional headers.\n\n**Upgrade path:** Update `builder-util-runtime` to `\u003e= 9.7.0`.\n\n---\n\n## Workarounds\n\nThere is no configuration-level workaround that prevents header forwarding in affected versions. The only mitigation short of upgrading is to avoid authenticated GitLab updater flows on versions `\u003c 9.7.0`.\n\nIf operating in a network environment where you control all possible redirect destinations, you may be able to prevent the token from reaching an attacker-controlled host through network-layer controls, but this is not a reliable mitigation.","status":"published","published":"2026-07-24T14:03:19Z","modified":"2026-07-24T14:16:01.807017022Z","cvss":[{"version":"4.0","score":8.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N","level":"high"}],"cwes":["CWE-200"],"updated_at":"2026-11-02T15:46:52.534897Z"},{"id":"openSUSE-SU-2026:11200-1","title":"heroic-games-launcher-2.22.0-4.1 on GA media","description":"These are all security issues fixed in the heroic-games-launcher-2.22.0-4.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-07-07T00:00:00Z","modified":"2026-07-09T10:00:07.077506571Z","updated_at":"2026-11-02T16:58:38.95195Z"}]}}
