fix(security): harden discovery routing and TLS pins
This commit is contained in:
35
src/cli/gateway-cli/discover.test.ts
Normal file
35
src/cli/gateway-cli/discover.test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { GatewayBonjourBeacon } from "../../infra/bonjour-discovery.js";
|
||||
import { pickBeaconHost, pickGatewayPort } from "./discover.js";
|
||||
|
||||
describe("gateway discover routing helpers", () => {
|
||||
it("prefers resolved service host over TXT hints", () => {
|
||||
const beacon: GatewayBonjourBeacon = {
|
||||
instanceName: "Test",
|
||||
host: "10.0.0.2",
|
||||
lanHost: "evil.example.com",
|
||||
tailnetDns: "evil.example.com",
|
||||
};
|
||||
expect(pickBeaconHost(beacon)).toBe("10.0.0.2");
|
||||
});
|
||||
|
||||
it("prefers resolved service port over TXT gatewayPort", () => {
|
||||
const beacon: GatewayBonjourBeacon = {
|
||||
instanceName: "Test",
|
||||
host: "10.0.0.2",
|
||||
port: 18789,
|
||||
gatewayPort: 12345,
|
||||
};
|
||||
expect(pickGatewayPort(beacon)).toBe(18789);
|
||||
});
|
||||
|
||||
it("falls back to TXT host/port when resolve data is missing", () => {
|
||||
const beacon: GatewayBonjourBeacon = {
|
||||
instanceName: "Test",
|
||||
lanHost: "test-host.local",
|
||||
gatewayPort: 18789,
|
||||
};
|
||||
expect(pickBeaconHost(beacon)).toBe("test-host.local");
|
||||
expect(pickGatewayPort(beacon)).toBe(18789);
|
||||
});
|
||||
});
|
||||
@@ -30,12 +30,15 @@ export function parseDiscoverTimeoutMs(raw: unknown, fallbackMs: number): number
|
||||
}
|
||||
|
||||
export function pickBeaconHost(beacon: GatewayBonjourBeacon): string | null {
|
||||
const host = beacon.tailnetDns || beacon.lanHost || beacon.host;
|
||||
// Security: TXT records are unauthenticated. Prefer the resolved service endpoint (SRV/A/AAAA)
|
||||
// over TXT-provided routing hints.
|
||||
const host = beacon.host || beacon.tailnetDns || beacon.lanHost;
|
||||
return host?.trim() ? host.trim() : null;
|
||||
}
|
||||
|
||||
export function pickGatewayPort(beacon: GatewayBonjourBeacon): number {
|
||||
const port = beacon.gatewayPort ?? 18789;
|
||||
// Security: TXT records are unauthenticated. Prefer the resolved service port over TXT gatewayPort.
|
||||
const port = beacon.port ?? beacon.gatewayPort ?? 18789;
|
||||
return port > 0 ? port : 18789;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user