From 4489ffb82eb98a8621c7ec86f3918912f5fb2eb2 Mon Sep 17 00:00:00 2001 From: Yann Soubeyrand <8511577+yann-soubeyrand@users.noreply.github.com> Date: Tue, 30 Dec 2025 10:53:04 +0100 Subject: [PATCH] fix(console): accept localhost redirect URIs without path nor port (#11001) # Which Problems Are Solved Some native OIDC applications use localhost without a path as redirect URI. Currently, setting http://localhost as a redirect URI leads to a compliance warning (Redirect URIs must begin with your own protocol, http://127.0.0.1, http://[::1] or http://localhost.), while http://localhost/some/path and http://localhost:some-port are accepted). # How the Problems Are Solved This PR parses the redirect URI instead of using prefix check to test if hostname part is localhost, 127.0.0.1 or [::1] (IPv6 addresses are canonicalized during parsing). # Additional Context This PR is a follow-up of https://github.com/zitadel/zitadel/pull/10836. Signed-off-by: Yann Soubeyrand <8511577+yann-soubeyrand@users.noreply.github.com> Co-authored-by: Ramon --- .../app/pipes/redirect-pipe/redirect.pipe.ts | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/console/src/app/pipes/redirect-pipe/redirect.pipe.ts b/console/src/app/pipes/redirect-pipe/redirect.pipe.ts index 45fc03075..c357d1682 100644 --- a/console/src/app/pipes/redirect-pipe/redirect.pipe.ts +++ b/console/src/app/pipes/redirect-pipe/redirect.pipe.ts @@ -6,32 +6,17 @@ import { Pipe, PipeTransform } from '@angular/core'; }) export class RedirectPipe implements PipeTransform { public transform(uri: string, isNative: boolean): boolean { - if (isNative) { - if ( - uri.startsWith('http://localhost/') || - uri.startsWith('http://localhost:') || - uri.startsWith('http://127.0.0.1') || - uri.startsWith('http://[::1]') || - uri.startsWith('http://[0:0:0:0:0:0:0:1]') || - uri.startsWith('https://localhost/') || - uri.startsWith('https://localhost:') || - uri.startsWith('https://127.0.0.1') || - uri.startsWith('https://[::1]') || - uri.startsWith('https://[0:0:0:0:0:0:0:1]') - ) { - return true; - } - if (!uri.startsWith('https://') && !uri.startsWith('http://')) { - return true; - } else { - return false; - } - } else { - if (uri.startsWith('https://')) { - return true; - } else { - return false; - } + const parsedURI = URL.parse(uri); + if (parsedURI === null) { + return false; } + if (!isNative) { + return parsedURI.protocol === 'https:'; + } + if (parsedURI.protocol !== 'http:' && parsedURI.protocol !== 'https:') { + return true; + } + const hostname = parsedURI.hostname; + return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]'; } }