fix: 收窄网络Agent IPv4保留段
This commit is contained in:
parent
21baade055
commit
9cea77ff49
@ -354,7 +354,7 @@ function port(value: unknown, name: string): number { if (typeof value !== 'numb
|
||||
function booleanValue(value: unknown, name: string): boolean { if (typeof value !== 'boolean') invalid(name); return value; }
|
||||
function enumValue<T extends string>(value: unknown, allowed: readonly T[], name: string): T { if (typeof value !== 'string' || !allowed.includes(value as T)) invalid(name); return value as T; }
|
||||
function isoString(value: unknown, name: string): string { const result = stringValue(value, name, 64); const match = RFC3339_PATTERN.exec(result); if (!match) invalid(name); const year = Number(match[1]); const month = Number(match[2]); const day = Number(match[3]); const hour = Number(match[4]); const minute = Number(match[5]); const second = Number(match[6]); const offsetHour = match[8] === 'Z' ? 0 : Number(match[10]); const offsetMinute = match[8] === 'Z' ? 0 : Number(match[11]); const leapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); const days = [31, leapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (month < 1 || month > 12 || day < 1 || day > days[month - 1] || hour > 23 || minute > 59 || second > 59 || offsetHour > 23 || offsetMinute > 59 || Number.isNaN(Date.parse(result))) invalid(name); return result; }
|
||||
function publicIpv4(value: unknown): string { const result = stringValue(value, 'publicIpv4', 15); const [a, b, c] = result.split('.').map(Number); if (isIP(result) !== 4 || a === 0 || a === 10 || a === 127 || a >= 224 || (a === 100 && b >= 64 && b <= 127) || (a === 169 && b === 254) || (a === 172 && b >= 16 && b <= 31) || (a === 192 && b === 168) || (a === 192 && b === 0) || (a === 192 && b === 88 && c === 99) || (a === 198 && (b === 18 || b === 19)) || (a === 198 && b === 51 && c === 100) || (a === 203 && b === 0 && c === 113)) invalid('publicIpv4'); return result; }
|
||||
function publicIpv4(value: unknown): string { const result = stringValue(value, 'publicIpv4', 15); const [a, b, c] = result.split('.').map(Number); if (isIP(result) !== 4 || a === 0 || a === 10 || a === 127 || a >= 224 || (a === 100 && b >= 64 && b <= 127) || (a === 169 && b === 254) || (a === 172 && b >= 16 && b <= 31) || (a === 192 && b === 168) || (a === 192 && b === 0 && (c === 0 || c === 2)) || (a === 192 && b === 88 && c === 99) || (a === 198 && (b === 18 || b === 19)) || (a === 198 && b === 51 && c === 100) || (a === 203 && b === 0 && c === 113)) invalid('publicIpv4'); return result; }
|
||||
function publicIpv6(value: unknown): string { const result = stringValue(value, 'publicIpv6', 45); if (isIP(result) !== 6) invalid('publicIpv6'); let normalized: string; try { const hostname = new URL(`http://[${result}]/`).hostname; normalized = hostname.slice(1, -1).toLowerCase(); } catch { invalid('publicIpv6'); } const firstHextet = Number.parseInt(normalized.split(':', 1)[0], 16); if (!Number.isInteger(firstHextet) || firstHextet < 0x2000 || firstHextet > 0x3fff) invalid('publicIpv6'); return normalized; }
|
||||
function digest(value: unknown): string { return createHash('sha256').update(goJsonStringify(value)).digest('hex'); }
|
||||
function goJsonStringify(value: unknown): string { return JSON.stringify(value).replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026').replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'); }
|
||||
|
||||
@ -117,7 +117,7 @@ describe('network agent MQTT v2 contract', () => {
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it.each(['192.0.0.1', '::ffff:8.8.8.8'])(
|
||||
it.each(['192.0.0.1', '192.0.2.1', '::ffff:8.8.8.8'])(
|
||||
'rejects non-dotted-public IPv4 %s',
|
||||
(publicIpv4) => {
|
||||
expect(() =>
|
||||
@ -139,6 +139,25 @@ describe('network agent MQTT v2 contract', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it('accepts 192.0.1.1 outside the reserved /24 ranges', () => {
|
||||
expect(
|
||||
parseEndpointEventV2(
|
||||
JSON.stringify({
|
||||
...eventValue(),
|
||||
endpoint: {
|
||||
mechanism: 'tcp_natmap',
|
||||
observedAt: '2026-07-26T00:01:00Z',
|
||||
publicIpv4: '192.0.1.1',
|
||||
publicPort: 443,
|
||||
validatedAt: '2026-07-26T00:01:10Z',
|
||||
validUntil: '2026-07-26T00:03:00Z',
|
||||
},
|
||||
type: 'published',
|
||||
}),
|
||||
),
|
||||
).toMatchObject({ endpoint: { publicIpv4: '192.0.1.1' } });
|
||||
});
|
||||
|
||||
it('uses shared UTF-8 byte limits for name, version, and global IPv6', () => {
|
||||
const desiredWithName = (name: string) => {
|
||||
const value = fixture('network-v2-desired.json');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user