Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass)
Summary
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.
Details
Vulnerable function: packages/server/routes/utils.js:393-395
const is_relative_url = (url) => {
return typeof url === "string" && !url.includes(":/") && !url.includes("//");
};
The function's intent is to allow only same-origin redirects, but the allow-list only checks for two literal substrings. It does not handle:
- 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/pathwith a base ofhttp://victim/resolves tohttp://evil.com/path. - non-
http(s):schemes that do not contain:/. The stringsjavascript:alert(1),data:text/html,...,vbscript:...all pass.
Vulnerable callsite: packages/server/auth/routes.js:1371-1376
} else if (
(req.body || {}).dest &&
is_relative_url(decodeURIComponent((req.body || {}).dest))
) {
res.redirect(decodeURIComponent((req.body || {}).dest));
} else res.redirect("/");
The 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.
PoC
Please extract the uploaded compressed file before proceeding
- ./setup.sh
- ./poc.sh
Impact
Any 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:
- Credential phishing — the attacker's site renders a forged "session expired, please log in again" prompt to capture the password the user just typed.
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| npm package | @saltcorn/server | < 1.4.6, >= 1.5.0-beta.0, < 1.5.6, >= 1.6.0-alpha.0, < 1.6.0-beta.5 | 1.4.6, 1.5.6, 1.6.0-beta.5 |
References
- CVSS 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- Weakness (CWE)
CWE-601- Platform
- npm
- Package
@saltcorn/server- Disclosed
- 16.04.2026
- Updated
- 11.10.2026 10:22
Sources and licenses
OSV / GitHub Advisory Database - GHSA-f3g8-9xv5-77gv - CC BY 4.0
Vulnerability history: @saltcorn/server
All published vulnerabilities of this package (npm package), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 9
- First → latest
- 10.2024 04.2026
- Without a fix
- 0
- Exploited in attacks
- 0
Severity breakdown
- Critical 2
- High 3
- Medium 4
Disclosures per year
- 2024: 5
- 2025: 0
- 2026: 4
-
Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass) this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.