diff --git a/ui/js/service-link.js b/ui/js/service-link.js index 7110d473..bede46fc 100644 --- a/ui/js/service-link.js +++ b/ui/js/service-link.js @@ -17,9 +17,14 @@ export function browserLink(raw) { return ''; } if (u.protocol !== 'http:' && u.protocol !== 'https:') return ''; - const host = u.hostname.toLowerCase().replace(/^\[|\]$/g, ''); + const host = u.hostname + .toLowerCase() + .replace(/^\[|\]$/g, '') + .replace(/\.$/, ''); if (host === 'localhost' || host.endsWith('.localhost') || host === 'host.docker.internal') return ''; - if (host === '::1' || host === '0.0.0.0' || /^127\./.test(host)) return ''; + if (host === '::1' || host === '::' || host === '0.0.0.0' || /^127\./.test(host)) return ''; + const mapped = /^::ffff:([0-9a-f]{1,4}):[0-9a-f]{1,4}$/.exec(host); + if (mapped && [0, 127].includes(parseInt(mapped[1], 16) >> 8)) return ''; if (!host.includes('.') && !host.includes(':')) return ''; u.username = ''; u.password = ''; diff --git a/ui/test/service-link.test.mjs b/ui/test/service-link.test.mjs index 9b0a2a68..75649a8d 100644 --- a/ui/test/service-link.test.mjs +++ b/ui/test/service-link.test.mjs @@ -18,6 +18,11 @@ test('an address only the server can reach gives no link', () => { 'http://127.0.0.1:3000', 'http://[::1]:80', 'http://host.docker.internal:9000', + 'http://localhost.:8080', + 'http://foo.localhost.', + 'http://[::ffff:127.0.0.1]:8080', + 'http://[::ffff:0.0.0.0]', + 'http://[::]:80', '', null, 'ftp://10.0.0.1',