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
- 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.
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
- 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.
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
- Clone target must be a subdirectory of
- Clone target must resolve inside
- Clone target parent must resolve inside
- Cloning from private/internal addresses is not allowed
- Git URLs must not include query strings or fragments
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)