cff816fa06
- Open redirect / client-side XSS (app-base.js): the post-login `redirect` read from the URL fragment was assigned straight to window.location. Add a same-origin guard (safeInternalPath) that rejects absolute URLs, protocol-relative "//host"/"/\\host", and scheme targets like "javascript:". Apply it in consumeTokenFragment and logInRedirect. - Server-side defense in depth: sanitize `redirect` when storing OidcState and when building the callback fragment (utils/safe_redirect.js, shared + unit-tested). - Missing rate limiting: throttle the unauthenticated auth endpoints (/login, /oidc/start, /oidc/callback) with express-rate-limit (60/IP/15m). Set `trust proxy: 1` so req.ip reflects the real client behind OpenResty. Adds test/unit/safe_redirect.test.js; unit suite 77 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
24 lines
744 B
JavaScript
24 lines
744 B
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Constrain a post-login redirect target to a same-origin path.
|
|
*
|
|
* Rejects anything that could leave the site or execute script:
|
|
* - absolute URLs ("https://evil.com") -> not a "/" path
|
|
* - protocol-relative ("//evil.com", "/\\evil.com") -> host takeover
|
|
* - scheme targets ("javascript:...", "data:...") -> XSS
|
|
* Anything not a plain "/path" falls back to "/".
|
|
*
|
|
* The browser has its own copy of this in public/lib/js/app-base.js; keep the
|
|
* two in sync.
|
|
*/
|
|
function safeInternalPath(path){
|
|
if(typeof path !== 'string' || path.charAt(0) !== '/'
|
|
|| path.charAt(1) === '/' || path.charAt(1) === '\\'){
|
|
return '/';
|
|
}
|
|
return path;
|
|
}
|
|
|
|
module.exports = {safeInternalPath};
|