abhigyanpatwari/GitNexus · error

Cloning from private/internal addresses is not allowed

Error message

Cloning from private/internal addresses is not allowed

What it means

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.

Solutions

  1. Replace the blocked hostname with a legitimate public git host — the URL is not a valid git remote.
  2. If this comes from user input, reject it: the block is intentional SSRF protection and should not be bypassed.
  3. Audit where the URL originates (config, PR metadata, API payload) and validate/allowlist git hosts upstream.
  4. For local testing, use a loopback-safe mock server that is not on BLOCKED_HOSTNAMES, or mock cloneOrPull in tests.

Example fix

// before
await cloneOrPull(userSuppliedRemoteUrl, dest); // http://169.254.169.254/...

// after
const host = new URL(userSuppliedRemoteUrl).hostname.toLowerCase();
if (!ALLOWED_GIT_HOSTS.has(host)) {
  throw new Error(`refusing non-allowlisted git host: ${host}`);
}
await cloneOrPull(userSuppliedRemoteUrl, dest);
Defensive patterns

Strategy: validation

Validate before calling

const host = new URL(u).hostname.toLowerCase();
const BLOCKED = new Set(['169.254.169.254', 'metadata.google.internal']);
if (BLOCKED.has(host)) throw new Error(`blocked host: ${host}`);

Type guard

const isPublicGitUrl = (u: string): boolean => {
  try {
    const p = new URL(u);
    if (!['https:', 'http:'].includes(p.protocol)) return false;
    return !BLOCKED_HOSTNAMES.has(p.hostname.toLowerCase());
  } catch { return false; }
};

Try / catch

try {
  validateGitUrl(url);
} catch (err) {
  if (err instanceof Error && err.message.includes('private/internal addresses')) {
    logger.error('SSRF-guard rejected URL; refusing to fetch');
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08). Data as JSON: /api/errors/775a1c36496d5ac1. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/core/net/url-guard.ts:36

  try {
    parsed = new URL(url);
  } catch {
    throw new Error('Invalid URL');
  }

  if (!['https:', 'http:'].includes(parsed.protocol)) {
    throw new Error('Only https:// and http:// git URLs are allowed');
  }

  if (parsed.search || parsed.hash) {
    throw new Error('Git URLs must not include query strings or fragments');
  }

  const host = parsed.hostname.toLowerCase();

  // Block known dangerous hostnames (cloud metadata services)
  if (BLOCKED_HOSTNAMES.has(host)) {
    throw new Error('Cloning from private/internal addresses is not allowed');
  }

  // Strip IPv6 brackets if present (URL parser behavior varies across Node versions)
  let normalizedHost = host;
  if (host.startsWith('[') && host.endsWith(']')) {
    normalizedHost = host.slice(1, -1);
  }

  // Check if this is an IPv6 address
  // Use manual colon detection as fallback since isIP may return 0 for some
  // normalized IPv6 forms (e.g. ::ffff:7f00:1)
  const isIPv6 = isIP(normalizedHost) === 6 || normalizedHost.includes(':');
  if (isIPv6) {
    assertNotPrivateIPv6(normalizedHost);
    return;
  }

  // Check if this is an IPv4 address (including numeric encodings)

View on GitHub (pinned to 0d1aed942f)