Skip to content

Commit 40437e9

Browse files
committed
harden legacy bitstream redirect namespace
1 parent 3a83eaf commit 40437e9

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

src/app/bitstream-page/legacy-bitstream-url-redirect.guard.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,19 @@ export const legacyBitstreamURLRedirectGuard: CanActivateFn = (
4848
getFirstCompletedRemoteData(),
4949
map((rd: RemoteData<Bitstream>) => {
5050
if (rd.hasSucceeded && !rd.hasNoContent) {
51-
// Harden namespace handling: trim slashes, neutralize absolute-like values, enforce root-relative path
5251
let nameSpace = (appConfig.ui.nameSpace || '').replace(/^\/+|\/+$/g, '');
53-
// Neutralize any absolute-like values (http:, https:, //)
54-
if (nameSpace.startsWith('http:') || nameSpace.startsWith('https:') || nameSpace.startsWith('//')) {
52+
// Neutralize any absolute-like values (http:, https:, //, protocol-relative URLs, or invalid characters)
53+
const allowedNamespaceRegex = /^[a-zA-Z0-9_-]+$/;
54+
// Check for absolute URLs, protocol-relative URLs, or invalid characters
55+
if (
56+
nameSpace.startsWith('http:') ||
57+
nameSpace.startsWith('https:') ||
58+
nameSpace.startsWith('//') ||
59+
nameSpace.match(/^\/[^\/]/) || // protocol-relative URL: single slash followed by non-slash
60+
!allowedNamespaceRegex.test(nameSpace)
61+
) {
5562
nameSpace = '';
5663
}
57-
// Always build path starting with /
5864
const redirectPath = nameSpace ? `/${nameSpace}/bitstreams/${rd.payload.uuid}/download` : `/bitstreams/${rd.payload.uuid}/download`;
5965
const redirectUrl = new URL(redirectPath, serverHardRedirectService.getCurrentOrigin()).href;
6066
serverHardRedirectService.redirect(redirectUrl, 301);

0 commit comments

Comments
 (0)