fix: support internal AgentBus attachments
This commit is contained in:
1 parent
cd45ce17d0
commit
161f90d09d
12 files changed
+96
-86
No files matched your search
@@ -158,41 +158,6 @@ export function decodeInlineInputAttachment(
|
||||
};
|
||||
}
|
||||
|
||||
function ipv4Number(address: string): number | null {
|
||||
const parts = address.split('.').map(Number);
|
||||
if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) return null;
|
||||
return (((parts[0] * 256 + parts[1]) * 256 + parts[2]) * 256 + parts[3]) >>> 0;
|
||||
}
|
||||
|
||||
function ipv4InCidr(address: string, network: string, prefix: number): boolean {
|
||||
const value = ipv4Number(address);
|
||||
const base = ipv4Number(network);
|
||||
if (value === null || base === null) return false;
|
||||
const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
|
||||
return (value & mask) === (base & mask);
|
||||
}
|
||||
|
||||
export function isPrivateOrReservedIp(address: string): boolean {
|
||||
const family = isIP(address);
|
||||
if (family === 4) {
|
||||
return [
|
||||
['0.0.0.0', 8], ['10.0.0.0', 8], ['100.64.0.0', 10], ['127.0.0.0', 8],
|
||||
['169.254.0.0', 16], ['172.16.0.0', 12], ['192.0.0.0', 24], ['192.0.2.0', 24],
|
||||
['192.168.0.0', 16], ['198.18.0.0', 15], ['198.51.100.0', 24], ['203.0.113.0', 24],
|
||||
['224.0.0.0', 4], ['240.0.0.0', 4]
|
||||
].some(([network, prefix]) => ipv4InCidr(address, String(network), Number(prefix)));
|
||||
}
|
||||
if (family !== 6) return true;
|
||||
const normalized = address.toLowerCase().split('%')[0];
|
||||
if (normalized === '::' || normalized === '::1') return true;
|
||||
const mapped = /^(?:::ffff:)?(\d+\.\d+\.\d+\.\d+)$/.exec(normalized);
|
||||
if (mapped) return isPrivateOrReservedIp(mapped[1]);
|
||||
return /^(?:fc|fd)/.test(normalized)
|
||||
|| /^fe[89ab]/.test(normalized)
|
||||
|| /^ff/.test(normalized)
|
||||
|| normalized.startsWith('2001:db8:');
|
||||
}
|
||||
|
||||
export function validateAgentBusAttachmentUrl(value: unknown): URL {
|
||||
let url: URL;
|
||||
try {
|
||||
@@ -203,12 +168,8 @@ export function validateAgentBusAttachmentUrl(value: unknown): URL {
|
||||
if (url.protocol !== 'https:' || url.username || url.password) {
|
||||
throw new InputAttachmentError('roster_attachment_url_unsafe', '名单附件必须使用不含用户名密码的 HTTPS URL。');
|
||||
}
|
||||
const hostname = url.hostname.replace(/^\[|\]$/g, '');
|
||||
if (!hostname || hostname.toLowerCase() === 'localhost') {
|
||||
throw new InputAttachmentError('roster_attachment_url_unsafe', '名单附件 URL 指向了不允许的地址。');
|
||||
}
|
||||
if (isIP(hostname) && isPrivateOrReservedIp(hostname)) {
|
||||
throw new InputAttachmentError('roster_attachment_url_unsafe', '名单附件 URL 指向了不允许的地址。');
|
||||
if (!url.hostname.replace(/^\[|\]$/g, '')) {
|
||||
throw new InputAttachmentError('roster_attachment_url_invalid', '名单附件 URL 无效。');
|
||||
}
|
||||
return url;
|
||||
}
|
||||
@@ -230,7 +191,9 @@ export function parseAgentBusInputAttachment(
|
||||
};
|
||||
}
|
||||
|
||||
async function publicAddresses(hostname: string): Promise<Array<{ address: string; family: number }>> {
|
||||
export async function resolveAgentBusAttachmentAddresses(
|
||||
hostname: string
|
||||
): Promise<Array<{ address: string; family: number }>> {
|
||||
if (isIP(hostname)) return [{ address: hostname, family: isIP(hostname) }];
|
||||
let addresses: Array<{ address: string; family: number }>;
|
||||
try {
|
||||
@@ -238,8 +201,8 @@ async function publicAddresses(hostname: string): Promise<Array<{ address: strin
|
||||
} catch {
|
||||
throw new InputAttachmentError('roster_attachment_host_unresolved', '名单附件地址无法解析。');
|
||||
}
|
||||
if (!addresses.length || addresses.some((item) => isPrivateOrReservedIp(item.address))) {
|
||||
throw new InputAttachmentError('roster_attachment_url_unsafe', '名单附件地址解析到了不允许的网络。');
|
||||
if (!addresses.length) {
|
||||
throw new InputAttachmentError('roster_attachment_host_unresolved', '名单附件地址无法解析。');
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
@@ -319,7 +282,7 @@ export async function downloadAgentBusInputAttachment(
|
||||
redirectCount = redirects;
|
||||
const dnsStartedAt = process.hrtime.bigint();
|
||||
emitAttachmentDiagnostic(diagnostic, 'dns_started', { redirect_count: redirects });
|
||||
const addresses = await publicAddresses(url.hostname.replace(/^\[|\]$/g, ''));
|
||||
const addresses = await resolveAgentBusAttachmentAddresses(url.hostname.replace(/^\[|\]$/g, ''));
|
||||
emitAttachmentDiagnostic(diagnostic, 'dns_validated', {
|
||||
redirect_count: redirects,
|
||||
address_count: addresses.length,
|
||||
|
||||
Reference in new issue
Block a user