fix: a security issue related to open external (#13864)

This commit is contained in:
Peng Xiao
2025-11-06 20:54:25 +08:00
committed by GitHub
parent dd676611ce
commit c9a4129a3e
7 changed files with 133 additions and 13 deletions
@@ -14,6 +14,7 @@ const trustedDomain = [
];
const logger = new DebugLogger('redirect_proxy');
const ALLOWED_PROTOCOLS = new Set(['http:', 'https:']);
/**
* /redirect-proxy page
@@ -32,6 +33,11 @@ export const loader: LoaderFunction = async ({ request }) => {
try {
const target = new URL(redirectUri);
if (!ALLOWED_PROTOCOLS.has(target.protocol)) {
logger.warn('Blocked redirect with disallowed protocol', target.protocol);
return { allow: false };
}
if (
target.hostname === window.location.hostname ||
trustedDomain.some(domain =>
@@ -46,7 +52,8 @@ export const loader: LoaderFunction = async ({ request }) => {
return { allow: false };
}
return { allow: true };
logger.warn('Blocked redirect to untrusted domain', redirectUri);
return { allow: false };
};
export const Component = () => {
@@ -39,6 +39,16 @@ export class UrlService extends Service {
* @param url only full url with http/https protocol is supported
*/
openExternal(url: string) {
let parsed: URL;
try {
parsed = new URL(url);
} catch {
throw new Error(`Invalid external URL: ${url}`);
}
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
throw new Error('only http/https URLs are supported');
}
if (BUILD_CONFIG.isWeb || BUILD_CONFIG.isMobileWeb) {
location.href = url;
} else {