abhigyanpatwari/GitNexus · error · Error
Invalid URL
Error message
Invalid URL
What it means
validateGitUrl's first step parses the input with new URL(); any string the WHATWG URL parser rejects — missing scheme, embedded spaces/control characters, bare 'github.com/user/repo' — throws and is rethrown as 'Invalid URL'. This is the malformed-input gate in front of the SSRF checks that follow.
Source
Thrown at gitnexus/src/server/git-clone.ts:83
// Cloud metadata hostnames that must never be reachable via user-supplied URLs
const BLOCKED_HOSTNAMES = new Set([
'localhost',
'metadata.google.internal',
'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);
}View on GitHub (pinned to aac7515d2a)
Solutions
- Trim whitespace/newlines from the URL before submitting
- Prepend https:// when the scheme is missing
- Run new URL(url) client-side as a pre-flight check
- Convert scp-style git@host:repo remotes to https://host/repo form
Example fix
// before const url = 'github.com/user/repo.git'; validateGitUrl(url); // Invalid URL // after const url = 'https://github.com/user/repo.git'; validateGitUrl(url); // ok
Defensive patterns
Strategy: validation
Validate before calling
function isParseableHttpUrl(s) {
if (typeof s !== 'string') return false;
try { const u = new URL(s.trim()); return u.protocol === 'https:' || u.protocol === 'http:'; }
catch { return false; }
} Type guard
function asTrimmedAbsoluteUrl(raw) {
const s = typeof raw === 'string' ? raw.trim() : '';
if (!s) return null;
const withScheme = /^[a-z][a-z0-9+.-]*:/i.test(s) ? s : `https://${s}`;
try { return new URL(withScheme).href; } catch { return null; }
} Try / catch
try { validateGitUrl(url); }
catch (e) {
if (e.message === 'Invalid URL') { const fixed = asTrimmedAbsoluteUrl(url); if (!fixed) throw e; validateGitUrl(fixed); }
else throw e;
} Prevention
- Trim pasted URLs and strip newlines before submitting
- Auto-prepend https:// when the scheme is missing
- Run new URL() in the client as the cheapest possible pre-flight
When it happens
Trigger: POST /api/analyze with url lacking a scheme ('github.com/user/repo.git'), containing raw spaces or newlines ('https:// ex ample.com'), or otherwise unparseable garbage such as pasted placeholder text.
Common situations: Users omitting https:// because git itself tolerates it; copy-paste introducing whitespace or a newline; frontends not trimming the field; scp-style 'git@host:repo' syntax, which the URL parser cannot parse at all.
Related errors
- Could not extract a valid repository name from URL
- Only https:// and http:// git URLs are allowed
- ${source} entries must all be strings.
- ${source} entries must not be empty.
- ${source} entry "${trimmed}" must be an identifier or member
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/f93b3052f52036ea.
Report an issue: GitHub.