Skip to content

Commit 0c1d829

Browse files
committed
Merge branch 'master' of github.com:chamilo/chamilo-lms
2 parents 297db13 + 7a81e72 commit 0c1d829

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

assets/vue/components/Login.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,12 @@ const isInIframe = window.self !== window.top
100100
if (isInIframe) {
101101
try {
102102
const parentUrl = window.top.location.href
103-
window.top.location.href = "/login?redirect=" + encodeURIComponent(parentUrl)
103+
const parent = new URL(parentUrl)
104+
// Only keep path + query + hash so redirect stays internal
105+
const redirectPath = parent.pathname + parent.search + parent.hash
106+
window.top.location.href = "/login?redirect=" + encodeURIComponent(redirectPath)
104107
} catch (e) {
108+
// Cross-origin or other error: just go to login without redirect
105109
window.top.location.href = "/login"
106110
}
107111
}

assets/vue/composables/auth/login.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ function normalizeRedirectUrl(rawRedirect) {
5252
try {
5353
const currentOrigin = window.location.origin
5454

55-
// root-relative path ("/resources/pages/edit?id=...")
55+
// Root-relative path ("/resources/pages/edit?id=...")
5656
if (rawRedirect.startsWith("/")) {
5757
const url = new URL(rawRedirect, currentOrigin)
5858
return url.pathname + url.search + url.hash
5959
}
6060

61-
// absolute URL - validate protocol first
61+
// Absolute URL - validate protocol first
6262
if (!isValidHttpUrl(rawRedirect)) {
6363
return null
6464
}
@@ -102,10 +102,11 @@ export function useLogin() {
102102
totp,
103103
}
104104

105-
// Add returnUrl if exists in query param
106-
const returnUrl = route.query.redirect?.toString() || null
107-
if (returnUrl) {
108-
payload.returnUrl = returnUrl
105+
// Add returnUrl if exists in query param, but sanitize it first
106+
const rawReturnUrl = route.query.redirect?.toString() || null
107+
const safeReturnUrl = rawReturnUrl ? normalizeRedirectUrl(rawReturnUrl) : null
108+
if (safeReturnUrl) {
109+
payload.returnUrl = safeReturnUrl
109110
}
110111

111112
const responseData =
@@ -122,7 +123,8 @@ export function useLogin() {
122123
// If backend forces password rotation, still apply locale before redirect
123124
if (responseData.rotate_password && responseData.redirect) {
124125
applyUserLocale(responseData)
125-
window.location.href = responseData.redirect
126+
const safeRedirect = normalizeRedirectUrl(responseData.redirect.toString())
127+
window.location.href = safeRedirect || "/"
126128
return { success: true, rotate: true }
127129
}
128130

@@ -135,8 +137,10 @@ export function useLogin() {
135137
// Terms and conditions redirect (apply locale before navigating)
136138
if (responseData.load_terms && responseData.redirect) {
137139
applyUserLocale(responseData)
138-
window.location.href = responseData.redirect
139-
return { success: true, redirect: responseData.redirect }
140+
const safeRedirect = normalizeRedirectUrl(responseData.redirect.toString())
141+
const target = safeRedirect || "/"
142+
window.location.href = target
143+
return { success: true, redirect: target }
140144
}
141145

142146
// External redirect param (apply locale before navigating)
@@ -147,7 +151,6 @@ export function useLogin() {
147151
const safeRedirect = normalizeRedirectUrl(rawRedirect)
148152

149153
if (safeRedirect) {
150-
// Keep query params (e.g. "?id=/api/pages/6") intact on same origin
151154
// Full reload here is intentional so the full app shell is rebuilt.
152155
window.location.href = safeRedirect
153156
return { success: true }
@@ -157,7 +160,8 @@ export function useLogin() {
157160
// Fallback backend redirect (apply locale before navigating)
158161
if (responseData.redirect) {
159162
applyUserLocale(responseData)
160-
window.location.href = responseData.redirect
163+
const safeRedirect = normalizeRedirectUrl(responseData.redirect.toString())
164+
window.location.href = safeRedirect || "/"
161165
return { success: true }
162166
}
163167

src/CoreBundle/EventListener/ExceptionListener.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,15 @@ public function __invoke(ExceptionEvent $event): void
5252
) {
5353
// If no token (not logged in), redirect to login with "redirect" back param
5454
if (null === $this->tokenStorage->getToken()) {
55+
// Use only a relative path (path + query) for the redirect parameter
56+
$redirectPath = $request->getRequestUri();
57+
if (!\is_string($redirectPath) || '' === $redirectPath) {
58+
$redirectPath = '/';
59+
}
60+
5561
$loginUrl = $this->router->generate(
5662
'login',
57-
['redirect' => $request->getSchemeAndHttpHost().$request->getRequestUri()],
63+
['redirect' => $redirectPath],
5864
UrlGeneratorInterface::ABSOLUTE_URL
5965
);
6066
$event->setResponse(new RedirectResponse($loginUrl));

0 commit comments

Comments
 (0)