abhigyanpatwari/GitNexus · error · Error

Only https:// and http:// git URLs are allowed

Error message

Only https:// and http:// git URLs are allowed

What it means

After a successful URL parse, validateGitUrl allows only the https: and http: protocols; anything else — ssh:, git:, file:, ftp: — is rejected before any network activity. GitNexus's server-side clone path deliberately accepts only plain HTTP(S) so credentials and local filesystem access cannot be smuggled through other schemes.

Source

Thrown at gitnexus/src/server/git-clone.ts:87

  'metadata.azure.com',
  'metadata.internal',
]);

/**
 * Validate a git URL to prevent SSRF attacks.
 * Only allows https:// and http:// schemes. Blocks private/internal addresses,
 * IPv6 private ranges, cloud metadata hostnames, and numeric IP encodings.
 */
export function validateGitUrl(url: string): void {
  let parsed: URL;
  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');
  }

  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)

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Convert the remote to https form: https://github.com/user/repo.git (embed a token if the repo is private, per the API's token support)
  2. For a repo already on the server's disk, use the 'path' field (absolute path) instead of a url
  3. Ask the mirror operator to expose HTTPS

Example fix

# before
url = 'ssh://git@github.com/user/repo.git'

# after
url = 'https://github.com/user/repo.git'
Defensive patterns

Strategy: validation

Validate before calling

function toHttpsGitUrl(raw) {
  const s = raw.trim();
  if (s.startsWith('git@')) return 'https://' + s.slice(4).replace(':', '/'); // git@host:owner/repo -> https://host/owner/repo
  const u = new URL(s);
  if (u.protocol !== 'https:' && u.protocol !== 'http:') throw new Error('only https/http supported');
  return u.href;
}

Type guard

function isHttpGitUrl(s) {
  try { const u = new URL(s); return u.protocol === 'https:' || u.protocol === 'http:'; } catch { return false; }
}

Try / catch

try { validateGitUrl(url); }
catch (e) {
  if (/Only https:// and http:///.test(e.message)) { validateGitUrl(toHttpsGitUrl(url)); /* retry once with converted url */ }
  else throw e;
}

Prevention

When it happens

Trigger: POST /api/analyze with url='ssh://git@github.com/user/repo.git', 'git://github.com/user/repo.git', or 'file:///srv/repos/repo' — all parse cleanly but fail the protocol allowlist. (scp-style 'git@github.com:repo' never gets here; it dies earlier as 'Invalid URL'.)

Common situations: Pasting the SSH remote copied from `git remote -v`; attempting file:// clones of locally mounted repos; legacy git:// protocol URLs; internal mirrors that only expose ssh.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20). Data as JSON: /api/errors/5777598e56db2110. Report an issue: GitHub.