@robosystems/core 0.8.5 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/auth-core/sso.js +23 -1
- package/package.json +1 -1
package/auth-core/sso.js
CHANGED
|
@@ -9,6 +9,28 @@ const debugLog = (message, error) => {
|
|
|
9
9
|
console.debug(`[SSO] ${message}`, error);
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Reduce a `returnUrl` to a same-origin path, or reject it.
|
|
14
|
+
*
|
|
15
|
+
* The value reaches us from a query parameter (or the sessionStorage mirror of
|
|
16
|
+
* one), so it is attacker-controlled on any crafted SSO link: an absolute URL
|
|
17
|
+
* would bounce the freshly authenticated user to another site, and a
|
|
18
|
+
* `javascript:` payload would execute as this origin. Cross-app returns don't
|
|
19
|
+
* need the escape hatch — `getSSORedirectUrl` hands the path to the *target*
|
|
20
|
+
* app, which resolves it against its own origin — so a bare absolute path is
|
|
21
|
+
* the only shape we ever legitimately produce.
|
|
22
|
+
*/
|
|
23
|
+
const sanitizeReturnUrl = (returnUrl) => {
|
|
24
|
+
if (!returnUrl)
|
|
25
|
+
return null;
|
|
26
|
+
// `//host` and `/\host` are both protocol-relative once a browser
|
|
27
|
+
// normalises them, so a leading slash alone isn't enough.
|
|
28
|
+
if (!returnUrl.startsWith('/'))
|
|
29
|
+
return null;
|
|
30
|
+
if (returnUrl.startsWith('//') || returnUrl.startsWith('/\\'))
|
|
31
|
+
return null;
|
|
32
|
+
return returnUrl;
|
|
33
|
+
};
|
|
12
34
|
export class SSOManager {
|
|
13
35
|
constructor(apiUrl) {
|
|
14
36
|
this.authClient = new RoboSystemsAuthClient(apiUrl);
|
|
@@ -84,7 +106,7 @@ export class SSOManager {
|
|
|
84
106
|
debugLog('sessionStorage read failed during SSO login', error);
|
|
85
107
|
}
|
|
86
108
|
const finalSessionId = sessionId; // Only use URL parameter for session ID
|
|
87
|
-
const finalReturnUrl = returnUrl || sessionStorageReturn;
|
|
109
|
+
const finalReturnUrl = sanitizeReturnUrl(returnUrl || sessionStorageReturn);
|
|
88
110
|
if (!finalSessionId) {
|
|
89
111
|
return null;
|
|
90
112
|
}
|
package/package.json
CHANGED