MCPcopy Create free account
hub / github.com/TestSprite/testsprite-cli / assertNotLocal

Function assertNotLocal

src/lib/target-url.ts:31–87  ·  view source on GitHub ↗
(rawUrl: string)

Source from the content-addressed store, hash-verified

29 * Silently returns on allowed URLs.
30 */
31export function assertNotLocal(rawUrl: string): void {
32 let parsed: URL;
33 try {
34 parsed = new URL(rawUrl);
35 } catch {
36 throw localTargetError('target-url', 'must be a valid URL');
37 }
38
39 // Scheme check.
40 if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
41 throw localTargetError('target-url', 'must use http or https scheme');
42 }
43
44 const host = parsed.hostname.toLowerCase();
45
46 // Loopback / unspecified.
47 if (host === 'localhost' || host === '0.0.0.0') {
48 throw localTargetError('target-url', 'localhost targets are not allowed', LOCAL_DEV_HINT);
49 }
50 // IPv6 literals. Node's URL parser wraps IPv6 hosts in brackets and
51 // normalizes IPv4-mapped forms to hex (`http://[::ffff:127.0.0.1]` →
52 // hostname `[::ffff:7f00:1]`). A dotted-form string check alone would miss
53 // the normalized variant, so we strip the brackets and classify the
54 // address family explicitly.
55 if (host.startsWith('[') && host.endsWith(']')) {
56 assertNotLocalIpv6(host.slice(1, -1));
57 }
58
59 // 127.0.0.0/8 loopback range.
60 if (/^127\.\d+\.\d+\.\d+$/.test(host)) {
61 throw localTargetError('target-url', 'loopback addresses are not allowed', LOCAL_DEV_HINT);
62 }
63
64 // AWS instance-metadata service (168 and 169 prefixes used for IMDS).
65 if (host === '169.254.169.254') {
66 throw localTargetError(
67 'target-url',
68 '169.254.169.254 (AWS metadata service) is not allowed',
69 LOCAL_DEV_HINT,
70 );
71 }
72
73 // 169.254.x.x link-local (IPv4).
74 if (/^169\.254\.\d+\.\d+$/.test(host)) {
75 throw localTargetError('target-url', 'link-local addresses are not allowed', LOCAL_DEV_HINT);
76 }
77
78 // RFC1918 literal IP addresses only — hostnames that resolve to private
79 // IPs are the backend's concern (DNS resolution is expensive CLI-side).
80 if (isRfc1918Literal(host)) {
81 throw localTargetError(
82 'target-url',
83 'private/RFC1918 addresses are not allowed',
84 LOCAL_DEV_HINT,
85 );
86 }
87}
88

Callers 9

runCreateFunction · 0.85
runCreateFromPlanFunction · 0.85
runCreateBatchFunction · 0.85
runTestRunFunction · 0.85
runCreateFunction · 0.85
runUpdateFunction · 0.85
expectBlockedFunction · 0.85
expectAllowedFunction · 0.85
target-url.spec.tsFile · 0.85

Calls 3

localTargetErrorFunction · 0.85
assertNotLocalIpv6Function · 0.85
isRfc1918LiteralFunction · 0.85

Tested by 2

expectBlockedFunction · 0.68
expectAllowedFunction · 0.68