mirror of
https://github.com/echore/vault-autopilot.git
synced 2026-07-22 08:34:00 +00:00
fix: close trailing-dot bypass in private-host check
new URL() keeps the trailing dot on FQDN hostnames ('localhost.',
'printer.local.') while stripping it from IPv4, so those slipped past
the loopback/.local literal checks. Strip one trailing dot before the
compares. Found in final whole-branch review.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
99f8435e41
commit
074ecf9bc9
2 changed files with 3 additions and 1 deletions
|
|
@ -26,7 +26,7 @@ export function sanitize(str: string): string {
|
|||
// IPs are accepted — DNS-rebinding protection is out of scope for a desktop
|
||||
// plugin talking to public CDNs.
|
||||
function isPrivateHost(hostname: string): boolean {
|
||||
let h = hostname.replace(/^\[|\]$/g, '').toLowerCase();
|
||||
let h = hostname.replace(/^\[|\]$/g, '').toLowerCase().replace(/\.$/, '');
|
||||
if (h === 'localhost' || h.endsWith('.local')) return true;
|
||||
if (h.startsWith('::ffff:')) {
|
||||
// IPv4-mapped IPv6; the URL parser serializes it as hex groups
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ describe('assertDownloadable', () => {
|
|||
expect(() => assertDownloadable('http://127.0.0.1:8080/x')).toThrow();
|
||||
expect(() => assertDownloadable('http://127.8.9.10/x')).toThrow();
|
||||
expect(() => assertDownloadable('http://[::1]/x')).toThrow();
|
||||
expect(() => assertDownloadable('http://localhost./x')).toThrow(); // FQDN trailing dot
|
||||
expect(() => assertDownloadable('http://printer.local./x')).toThrow();
|
||||
expect(() => assertDownloadable('http://0x7f000001/x')).toThrow(); // URL-normalized to 127.0.0.1
|
||||
expect(() => assertDownloadable('http://[::ffff:127.0.0.1]/x')).toThrow();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue