{"id":"CVE-2026-42259","aliases":["EUVD-2026-28431","GHSA-f3g8-9xv5-77gv"],"status":"published","title":"Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass)","description":"Saltcorn is an extensible, open source, no-code database application builder. Prior to versions 1.4.6, 1.5.6, and 1.6.0-beta.5, Saltcorn validates the post-login dest parameter with a string check that only blocks :/ and //. Because all WHATWG-compliant browsers normalise backslashes (\\) to forward slashes (/) for special schemes, a payload such as /\\evil.com/path slips through is_relative_url(), is emitted unchanged in the HTTP Location header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL. This issue has been patched in versions 1.4.6, 1.5.6, and 1.6.0-beta.5.","severity":{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00339,"percentile":0.27577,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-601"],"published":"2026-04-16T23:00:45Z","modified":"2026-10-28T02:31:10Z","fixes":[{"ecosystem":"npm","package":"@saltcorn/server","fixed_in":["1.4.6","1.5.6","1.6.0-beta.5"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"@saltcorn/server","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.4.6"}]}]},{"source":"ghsa","ecosystem":"npm","package":"@saltcorn/server","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.5.0-beta.0"},{"fixed":"1.5.6"}]}]},{"source":"ghsa","ecosystem":"npm","package":"@saltcorn/server","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.6.0-alpha.0"},{"fixed":"1.6.0-beta.5"}]}]},{"source":"osv","ecosystem":"npm","package":"@saltcorn/server","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.4.6"}]}]},{"source":"osv","ecosystem":"npm","package":"@saltcorn/server","ranges":[{"type":"SEMVER","events":[{"introduced":"1.5.0-beta.0"},{"fixed":"1.5.6"}]}]},{"source":"osv","ecosystem":"npm","package":"@saltcorn/server","ranges":[{"type":"SEMVER","events":[{"introduced":"1.6.0-alpha.0"},{"fixed":"1.6.0-beta.5"}]}]}],"products":[{"vendor":"saltcorn","product":"saltcorn"}],"references":[{"url":"https://github.com/saltcorn/saltcorn/security/advisories/GHSA-f3g8-9xv5-77gv","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42259","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-f3g8-9xv5-77gv"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/42xxx/CVE-2026-42259.json","tags":["advisory"]},{"url":"https://github.com/saltcorn/saltcorn","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-42259","title":"Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass)","description":"Saltcorn is an extensible, open source, no-code database application builder. Prior to versions 1.4.6, 1.5.6, and 1.6.0-beta.5, Saltcorn validates the post-login dest parameter with a string check that only blocks :/ and //. Because all WHATWG-compliant browsers normalise backslashes (\\) to forward slashes (/) for special schemes, a payload such as /\\evil.com/path slips through is_relative_url(), is emitted unchanged in the HTTP Location header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL. This issue has been patched in versions 1.4.6, 1.5.6, and 1.6.0-beta.5.","status":"published","published":"2026-05-07T18:54:57.234Z","modified":"2026-05-08T22:56:33.661Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N","level":"medium","assessor":"cna"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T13:40:23.731501Z"}],"euvd":[{"id":"EUVD-2026-28431","description":"Saltcorn is an extensible, open source, no-code database application builder. Prior to versions 1.4.6, 1.5.6, and 1.6.0-beta.5, Saltcorn validates the post-login dest parameter with a string check that only blocks :/ and //. Because all WHATWG-compliant browsers normalise backslashes (\\) to forward slashes (/) for special schemes, a payload such as /\\evil.com/path slips through is_relative_url(), is emitted unchanged in the HTTP Location header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL. This issue has been patched in versions 1.4.6, 1.5.6, and 1.6.0-beta.5.","status":"published","published":"2026-05-07T18:54:57Z","modified":"2026-05-08T22:56:33Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N","level":"medium"}],"updated_at":"2026-11-02T19:05:14.089367Z"}],"ghsa":[{"id":"GHSA-f3g8-9xv5-77gv","title":"Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass)","description":"### Summary\nSaltcorn validates the post-login `dest` parameter with a string check that only blocks `:/` and `//`. Because all WHATWG-compliant browsers normalise backslashes (`\\`) to forward slashes (`/`) for special schemes, a payload such as `/\\evil.com/path` slips through `is_relative_url()`, is emitted unchanged in the HTTP `Location` header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL.\n\n### Details\nVulnerable function: `packages/server/routes/utils.js:393-395`\n\n```js\nconst is_relative_url = (url) =\u003e {\n  return typeof url === \"string\" \u0026\u0026 !url.includes(\":/\") \u0026\u0026 !url.includes(\"//\");\n};\n```\n\nThe function's intent is to allow only same-origin redirects, but the allow-list only checks for two literal substrings. It does not handle:\n- backslash characters, which WHATWG URL parsing (used by every modern browser) treats as forward slashes for the special schemes `http`, `https`, `ftp`, `ws`, `wss`. A URL parser fed `/\\evil.com/path` with a base of `http://victim/` resolves to `http://evil.com/path`.\n- non-`http(s):` schemes that do not contain `:/`. The strings `javascript:alert(1)`, `data:text/html,...`, `vbscript:...` all pass.\n\nVulnerable callsite: `packages/server/auth/routes.js:1371-1376`\n\n```js\n} else if (\n  (req.body || {}).dest \u0026\u0026\n  is_relative_url(decodeURIComponent((req.body || {}).dest))\n) {\n  res.redirect(decodeURIComponent((req.body || {}).dest));\n} else res.redirect(\"/\");\n```\n\nThe body's `dest` is URL-decoded twice (once by body-parser, once by the explicit `decodeURIComponent`) and the same value is passed to `res.redirect`. Express 5's `res.redirect` runs the value through `encodeurl@2.0.0`, whose whitelist character class `[^\\x21\\x23-\\x3B\\x3D\\x3F-\\x5F\\x61-\\x7A\\x7C\\x7E]` includes `\\x5C` (backslash). The backslash is therefore not percent-encoded and ends up verbatim in the `Location` response header.\n\n### PoC\n[poc.zip](https://github.com/user-attachments/files/26678853/poc.zip)\n\nPlease extract the uploaded compressed file before proceeding\n1. ./setup.sh\n2. ./poc.sh\n\n\u003cimg width=\"419\" height=\"71\" alt=\"스크린샷 2026-04-13 오후 11 44 36\" src=\"https://github.com/user-attachments/assets/9c919ed4-167b-47e3-9873-733f97b44bf0\" /\u003e\n\n### Impact\nAny user who can be lured into clicking a Saltcorn login URL crafted by the attacker will, after submitting their valid credentials, be redirected to an attacker-controlled origin. The redirect happens under the trusted Saltcorn domain, so the user has no visual cue that they are about to leave the site. Realistic abuse patterns:\n\n- Credential phishing — the attacker's site renders a forged \"session expired, please log in again\" prompt to capture the password the user just typed.","status":"published","published":"2026-04-16T23:00:45Z","modified":"2026-05-11T13:29:08Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N","level":"medium"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T14:40:05.816188Z"}],"nvd":[{"id":"CVE-2026-42259","description":"Saltcorn is an extensible, open source, no-code database application builder. Prior to versions 1.4.6, 1.5.6, and 1.6.0-beta.5, Saltcorn validates the post-login dest parameter with a string check that only blocks :/ and //. Because all WHATWG-compliant browsers normalise backslashes (\\) to forward slashes (/) for special schemes, a payload such as /\\evil.com/path slips through is_relative_url(), is emitted unchanged in the HTTP Location header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL. This issue has been patched in versions 1.4.6, 1.5.6, and 1.6.0-beta.5.","status":"published","published":"2026-05-07T20:16:44.4Z","modified":"2026-06-17T10:47:35.8Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/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":"medium","assessor":"secondary"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T14:12:17.842772Z"}],"osv":[{"id":"CVE-2026-42259","title":"Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass)","description":"Saltcorn is an extensible, open source, no-code database application builder. Prior to versions 1.4.6, 1.5.6, and 1.6.0-beta.5, Saltcorn validates the post-login dest parameter with a string check that only blocks :/ and //. Because all WHATWG-compliant browsers normalise backslashes (\\) to forward slashes (/) for special schemes, a payload such as /\\evil.com/path slips through is_relative_url(), is emitted unchanged in the HTTP Location header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL. This issue has been patched in versions 1.4.6, 1.5.6, and 1.6.0-beta.5.","status":"published","published":"2026-05-07T18:54:57.234Z","modified":"2026-10-28T02:31:10.912736072Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N","level":"medium"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T15:45:04.117819Z"},{"id":"GHSA-f3g8-9xv5-77gv","title":"Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass)","description":"### Summary\nSaltcorn validates the post-login `dest` parameter with a string check that only blocks `:/` and `//`. Because all WHATWG-compliant browsers normalise backslashes (`\\`) to forward slashes (`/`) for special schemes, a payload such as `/\\evil.com/path` slips through `is_relative_url()`, is emitted unchanged in the HTTP `Location` header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL.\n\n### Details\nVulnerable function: `packages/server/routes/utils.js:393-395`\n\n```js\nconst is_relative_url = (url) =\u003e {\n  return typeof url === \"string\" \u0026\u0026 !url.includes(\":/\") \u0026\u0026 !url.includes(\"//\");\n};\n```\n\nThe function's intent is to allow only same-origin redirects, but the allow-list only checks for two literal substrings. It does not handle:\n- backslash characters, which WHATWG URL parsing (used by every modern browser) treats as forward slashes for the special schemes `http`, `https`, `ftp`, `ws`, `wss`. A URL parser fed `/\\evil.com/path` with a base of `http://victim/` resolves to `http://evil.com/path`.\n- non-`http(s):` schemes that do not contain `:/`. The strings `javascript:alert(1)`, `data:text/html,...`, `vbscript:...` all pass.\n\nVulnerable callsite: `packages/server/auth/routes.js:1371-1376`\n\n```js\n} else if (\n  (req.body || {}).dest \u0026\u0026\n  is_relative_url(decodeURIComponent((req.body || {}).dest))\n) {\n  res.redirect(decodeURIComponent((req.body || {}).dest));\n} else res.redirect(\"/\");\n```\n\nThe body's `dest` is URL-decoded twice (once by body-parser, once by the explicit `decodeURIComponent`) and the same value is passed to `res.redirect`. Express 5's `res.redirect` runs the value through `encodeurl@2.0.0`, whose whitelist character class `[^\\x21\\x23-\\x3B\\x3D\\x3F-\\x5F\\x61-\\x7A\\x7C\\x7E]` includes `\\x5C` (backslash). The backslash is therefore not percent-encoded and ends up verbatim in the `Location` response header.\n\n### PoC\n[poc.zip](https://github.com/user-attachments/files/26678853/poc.zip)\n\nPlease extract the uploaded compressed file before proceeding\n1. ./setup.sh\n2. ./poc.sh\n\n\u003cimg width=\"419\" height=\"71\" alt=\"스크린샷 2026-04-13 오후 11 44 36\" src=\"https://github.com/user-attachments/assets/9c919ed4-167b-47e3-9873-733f97b44bf0\" /\u003e\n\n### Impact\nAny user who can be lured into clicking a Saltcorn login URL crafted by the attacker will, after submitting their valid credentials, be redirected to an attacker-controlled origin. The redirect happens under the trusted Saltcorn domain, so the user has no visual cue that they are about to leave the site. Realistic abuse patterns:\n\n- Credential phishing — the attacker's site renders a forged \"session expired, please log in again\" prompt to capture the password the user just typed.","status":"published","published":"2026-04-16T23:00:45Z","modified":"2026-05-11T13:53:18.140132Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N","level":"medium"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T15:46:45.639885Z"}]}}
