mirror of
https://github.com/HangarMC/Hangar.git
synced 2025-02-17 15:01:42 +08:00
fix: only allow relative urls in redirects
This commit is contained in:
parent
1f46cbf4b1
commit
c4585f7e41
@ -17,6 +17,8 @@ import io.papermc.hangar.service.ValidationService;
|
||||
import io.papermc.hangar.service.internal.auth.SSOService;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -51,9 +53,9 @@ public class LoginController extends HangarComponent {
|
||||
|
||||
final UserTable fakeUser = this.authenticationService.loginAsFakeUser();
|
||||
this.tokenService.issueRefreshToken(fakeUser);
|
||||
return this.addBaseAndRedirect(returnUrl);
|
||||
return this.addBaseAndRedirect(this.cutoffAbsoluteUrls(returnUrl));
|
||||
} else {
|
||||
this.response.addCookie(new Cookie("url", returnUrl));
|
||||
this.response.addCookie(new Cookie("url", this.cutoffAbsoluteUrls(returnUrl)));
|
||||
return this.redirectToSso(this.ssoService.getLoginUrl(this.config.getBaseUrl() + "/login"));
|
||||
}
|
||||
}
|
||||
@ -70,7 +72,18 @@ public class LoginController extends HangarComponent {
|
||||
throw new HangarApiException("nav.user.error.invalidUsername");
|
||||
}
|
||||
this.tokenService.issueRefreshToken(user);
|
||||
return this.addBaseAndRedirect(url);
|
||||
return this.addBaseAndRedirect(this.cutoffAbsoluteUrls(url));
|
||||
}
|
||||
|
||||
private String cutoffAbsoluteUrls(final String url) {
|
||||
try {
|
||||
if (!new URI(url).isAbsolute()) {
|
||||
return url;
|
||||
}
|
||||
} catch (final URISyntaxException ignored) {
|
||||
// ignored
|
||||
}
|
||||
return "/";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@ -93,16 +106,16 @@ public class LoginController extends HangarComponent {
|
||||
@GetMapping(path = "/logout", params = "returnUrl")
|
||||
public String logout(@RequestParam(defaultValue = "/?loggedOut") final String returnUrl) {
|
||||
if (this.config.fakeUser.enabled()) {
|
||||
this.response.addCookie(new Cookie("url", returnUrl));
|
||||
this.response.addCookie(new Cookie("url", this.cutoffAbsoluteUrls(returnUrl)));
|
||||
return "/fake-logout";
|
||||
} else {
|
||||
this.response.addCookie(new Cookie("url", returnUrl));
|
||||
this.response.addCookie(new Cookie("url", this.cutoffAbsoluteUrls(returnUrl)));
|
||||
final Optional<HangarPrincipal> principal = this.getOptionalHangarPrincipal();
|
||||
if (principal.isPresent()) {
|
||||
return this.ssoService.getLogoutUrl(this.config.getBaseUrl() + "/handle-logout", principal.get()).url();
|
||||
} else {
|
||||
this.tokenService.invalidateToken(null);
|
||||
return this.addBase(returnUrl);
|
||||
return this.addBase(this.cutoffAbsoluteUrls(returnUrl));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,7 +131,7 @@ public class LoginController extends HangarComponent {
|
||||
if (session != null) {
|
||||
session.invalidate();
|
||||
}
|
||||
return this.addBaseAndRedirect(returnUrl);
|
||||
return this.addBaseAndRedirect(this.cutoffAbsoluteUrls(returnUrl));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/handle-logout", params = "state")
|
||||
@ -143,7 +156,7 @@ public class LoginController extends HangarComponent {
|
||||
if (session != null) {
|
||||
session.invalidate();
|
||||
}
|
||||
return this.addBaseAndRedirect(returnUrl);
|
||||
return this.addBaseAndRedirect(this.cutoffAbsoluteUrls(returnUrl));
|
||||
}
|
||||
|
||||
@GetMapping("/signup")
|
||||
@ -151,7 +164,7 @@ public class LoginController extends HangarComponent {
|
||||
if (this.config.fakeUser.enabled()) {
|
||||
throw new HangarApiException("nav.user.error.fakeUserEnabled", "Signup");
|
||||
}
|
||||
return new RedirectView(this.ssoService.getSignupUrl(returnUrl));
|
||||
return new RedirectView(this.ssoService.getSignupUrl(this.cutoffAbsoluteUrls(returnUrl)));
|
||||
}
|
||||
|
||||
@PostMapping("/sync")
|
||||
|
@ -5,7 +5,6 @@ import { useAuthStore } from "~/store/auth";
|
||||
import { useCookies } from "~/composables/useCookies";
|
||||
import { useInternalApi } from "~/composables/useApi";
|
||||
import { authLog } from "~/lib/composables/useLog";
|
||||
import { useConfig } from "~/lib/composables/useConfig";
|
||||
import { handleRequestError, useRequestEvent } from "#imports";
|
||||
import { useAxios } from "~/composables/useAxios";
|
||||
import { useNotificationStore } from "~/lib/store/notification";
|
||||
@ -16,12 +15,12 @@ class Auth {
|
||||
if (redirectUrl.endsWith("?loggedOut")) {
|
||||
redirectUrl = redirectUrl.replace("?loggedOut", "");
|
||||
}
|
||||
return `/login?returnUrl=${useConfig().publicHost}${redirectUrl}`;
|
||||
return `/login?returnUrl=${redirectUrl}`;
|
||||
}
|
||||
|
||||
async logout() {
|
||||
const result = await useAxios()
|
||||
.get(`/logout?returnUrl=${useConfig().publicHost}?loggedOut`)
|
||||
.get(`/logout?returnUrl=/?loggedOut`)
|
||||
.catch((e) => handleRequestError(e));
|
||||
if (result?.status === 200 && result?.data) {
|
||||
location.replace(result?.data);
|
||||
|
Loading…
Reference in New Issue
Block a user