mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
chore(ssrf): include lookup error code in error message
This commit is contained in:
@@ -16,11 +16,11 @@ function isAlwaysBlocked(ip: string): boolean {
|
|||||||
const addr = ip.startsWith('[') ? ip.slice(1, -1) : ip;
|
const addr = ip.startsWith('[') ? ip.slice(1, -1) : ip;
|
||||||
|
|
||||||
// Loopback
|
// Loopback
|
||||||
if (addr.startsWith("127.") || addr === '::1') return true;
|
if (addr.startsWith('127.') || addr === '::1') return true;
|
||||||
// Unspecified
|
// Unspecified
|
||||||
if (addr.startsWith("0.")) return true;
|
if (addr.startsWith('0.')) return true;
|
||||||
// Link-local / cloud metadata
|
// Link-local / cloud metadata
|
||||||
if (addr.startsWith("169.254.") || /^fe80:/i.test(addr)) return true;
|
if (addr.startsWith('169.254.') || /^fe80:/i.test(addr)) return true;
|
||||||
// IPv4-mapped loopback / link-local: ::ffff:127.x.x.x, ::ffff:169.254.x.x
|
// IPv4-mapped loopback / link-local: ::ffff:127.x.x.x, ::ffff:169.254.x.x
|
||||||
if (/^::ffff:127\./i.test(addr) || /^::ffff:169\.254\./i.test(addr)) return true;
|
if (/^::ffff:127\./i.test(addr) || /^::ffff:169\.254\./i.test(addr)) return true;
|
||||||
|
|
||||||
@@ -32,9 +32,9 @@ function isPrivateNetwork(ip: string): boolean {
|
|||||||
const addr = ip.startsWith('[') ? ip.slice(1, -1) : ip;
|
const addr = ip.startsWith('[') ? ip.slice(1, -1) : ip;
|
||||||
|
|
||||||
// RFC-1918 private ranges
|
// RFC-1918 private ranges
|
||||||
if (addr.startsWith("10.")) return true;
|
if (addr.startsWith('10.')) return true;
|
||||||
if (/^172\.(1[6-9]|2\d|3[01])\./.test(addr)) return true;
|
if (/^172\.(1[6-9]|2\d|3[01])\./.test(addr)) return true;
|
||||||
if (addr.startsWith("192.168.")) return true;
|
if (addr.startsWith('192.168.')) return true;
|
||||||
// CGNAT / Tailscale shared address space (100.64.0.0/10)
|
// CGNAT / Tailscale shared address space (100.64.0.0/10)
|
||||||
if (/^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./.test(addr)) return true;
|
if (/^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./.test(addr)) return true;
|
||||||
// IPv6 ULA (fc00::/7)
|
// IPv6 ULA (fc00::/7)
|
||||||
@@ -71,8 +71,9 @@ export async function checkSsrf(rawUrl: string, bypassInternalIpAllowed: boolean
|
|||||||
try {
|
try {
|
||||||
const result = await dns.lookup(hostname);
|
const result = await dns.lookup(hostname);
|
||||||
resolvedIp = result.address;
|
resolvedIp = result.address;
|
||||||
} catch {
|
} catch (error_) {
|
||||||
return { allowed: false, isPrivate: false, error: 'Could not resolve hostname' };
|
const code = error_ instanceof Error && 'code' in error_ ? String(error_.code) : 'unknown';
|
||||||
|
return { allowed: false, isPrivate: false, error: `Could not resolve hostname (${code})` };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAlwaysBlocked(resolvedIp)) {
|
if (isAlwaysBlocked(resolvedIp)) {
|
||||||
@@ -90,7 +91,8 @@ export async function checkSsrf(rawUrl: string, bypassInternalIpAllowed: boolean
|
|||||||
allowed: false,
|
allowed: false,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
resolvedIp,
|
resolvedIp,
|
||||||
error: 'Requests to private/internal network addresses are not allowed. Set ALLOW_INTERNAL_NETWORK=true to permit this for self-hosted setups.',
|
error:
|
||||||
|
'Requests to private/internal network addresses are not allowed. Set ALLOW_INTERNAL_NETWORK=true to permit this for self-hosted setups.',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return { allowed: true, isPrivate: true, resolvedIp };
|
return { allowed: true, isPrivate: true, resolvedIp };
|
||||||
@@ -187,7 +189,7 @@ export async function safeFetchFollow(
|
|||||||
// (2xx/4xx/5xx, or a 3xx with no Location) is the final response.
|
// (2xx/4xx/5xx, or a 3xx with no Location) is the final response.
|
||||||
const status = typeof response.status === 'number' ? response.status : 0;
|
const status = typeof response.status === 'number' ? response.status : 0;
|
||||||
const isRedirectStatus = status >= 300 && status < 400;
|
const isRedirectStatus = status >= 300 && status < 400;
|
||||||
const location = isRedirectStatus ? response.headers?.get('location') ?? null : null;
|
const location = isRedirectStatus ? (response.headers?.get('location') ?? null) : null;
|
||||||
if (!location) {
|
if (!location) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user