{"record":{"id":"775a1c36496d5ac1","repo":"abhigyanpatwari/GitNexus","slug":"cloning-from-private-internal-addresses-is-not-all-775a1c","errorCode":null,"errorMessage":"Cloning from private/internal addresses is not allowed","messagePattern":"Cloning from private/internal addresses is not allowed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/net/url-guard.ts","lineNumber":36,"sourceCode":"  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error('Invalid URL');\n  }\n\n  if (!['https:', 'http:'].includes(parsed.protocol)) {\n    throw new Error('Only https:// and http:// git URLs are allowed');\n  }\n\n  if (parsed.search || parsed.hash) {\n    throw new Error('Git URLs must not include query strings or fragments');\n  }\n\n  const host = parsed.hostname.toLowerCase();\n\n  // Block known dangerous hostnames (cloud metadata services)\n  if (BLOCKED_HOSTNAMES.has(host)) {\n    throw new Error('Cloning from private/internal addresses is not allowed');\n  }\n\n  // Strip IPv6 brackets if present (URL parser behavior varies across Node versions)\n  let normalizedHost = host;\n  if (host.startsWith('[') && host.endsWith(']')) {\n    normalizedHost = host.slice(1, -1);\n  }\n\n  // Check if this is an IPv6 address\n  // Use manual colon detection as fallback since isIP may return 0 for some\n  // normalized IPv6 forms (e.g. ::ffff:7f00:1)\n  const isIPv6 = isIP(normalizedHost) === 6 || normalizedHost.includes(':');\n  if (isIPv6) {\n    assertNotPrivateIPv6(normalizedHost);\n    return;\n  }\n\n  // Check if this is an IPv4 address (including numeric encodings)","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/core/net/url-guard.ts#L18-L54","documentation":"validateGitUrl blocks known dangerous hostnames (BLOCKED_HOSTNAMES, e.g. cloud metadata service endpoints like 169.254.169.254) as an SSRF defense. Cloning from such a host could exfiltrate cloud credentials, so any URL whose hostname is on the blocklist throws this error.","triggerScenarios":"Calling validateGitUrl (or cloneOrPull / normalizedRegistry / sanitizedHttpUrl) with a URL whose hostname (lowercased) is present in BLOCKED_HOSTNAMES — e.g. http://169.254.169.254/latest/meta-data.","commonSituations":"A malicious or misconfigured repo URL pointing at a cloud metadata endpoint in CI; template/config injection where an attacker controls the remote URL; tests accidentally using the metadata IP as a fake host.","solutions":["Replace the blocked hostname with a legitimate public git host — the URL is not a valid git remote.","If this comes from user input, reject it: the block is intentional SSRF protection and should not be bypassed.","Audit where the URL originates (config, PR metadata, API payload) and validate/allowlist git hosts upstream.","For local testing, use a loopback-safe mock server that is not on BLOCKED_HOSTNAMES, or mock cloneOrPull in tests."],"exampleFix":"// before\nawait cloneOrPull(userSuppliedRemoteUrl, dest); // http://169.254.169.254/...\n\n// after\nconst host = new URL(userSuppliedRemoteUrl).hostname.toLowerCase();\nif (!ALLOWED_GIT_HOSTS.has(host)) {\n  throw new Error(`refusing non-allowlisted git host: ${host}`);\n}\nawait cloneOrPull(userSuppliedRemoteUrl, dest);","handlingStrategy":"validation","validationCode":"const host = new URL(u).hostname.toLowerCase();\nconst BLOCKED = new Set(['169.254.169.254', 'metadata.google.internal']);\nif (BLOCKED.has(host)) throw new Error(`blocked host: ${host}`);","typeGuard":"const isPublicGitUrl = (u: string): boolean => {\n  try {\n    const p = new URL(u);\n    if (!['https:', 'http:'].includes(p.protocol)) return false;\n    return !BLOCKED_HOSTNAMES.has(p.hostname.toLowerCase());\n  } catch { return false; }\n};","tryCatchPattern":"try {\n  validateGitUrl(url);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('private/internal addresses')) {\n    logger.error('SSRF-guard rejected URL; refusing to fetch');\n    return;\n  }\n  throw err;\n}","preventionTips":["Allowlist trusted git hosts before accepting remote URLs from users.","Never construct remote URLs from untrusted PR/API input without validation.","Keep the BLOCKED_HOSTNAMES list current with your cloud provider's metadata endpoints."],"tags":["security","ssrf","url","git","blocked-host"],"backgroundTag":"invalid-url-format","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-09-08T00:40:44.970Z","contentChangedAt":"2026-09-08T00:40:44.970Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}