Potential fix for code scanning alert no. 3: Incomplete URL substring sanitization

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
This commit is contained in:
Georg Bauer
2026-02-16 17:48:48 +01:00
committed by GitHub
parent 95705f6c92
commit f03e4bb827

View File

@@ -239,18 +239,79 @@ export class GitEngine {
]; ];
} }
/**
* Extracts the host portion from common Git URL formats.
*
* Supports:
* - HTTPS/HTTP: https://host/owner/repo.git
* - SSH: git@host:owner/repo.git
* - SSH URL: ssh://git@host/owner/repo.git
*/
private getHostFromGitUrl(value: string): string | null {
const trimmed = value.trim();
// Try standard URL parsing for HTTP(S) and ssh:// URLs
try {
const url = new URL(trimmed);
if (url.hostname) {
return url.hostname.toLowerCase();
}
} catch {
// Fall through to manual parsing for scp-like SSH syntax
}
// Match scp-like SSH syntax: [user@]host:owner/repo.git
// Examples:
// git@github.com:owner/repo.git
// git@gitlab.example.com:owner/repo.git
const sshLikeMatch = trimmed.match(/^[^@]+@([^:]+):.+$/);
if (sshLikeMatch && sshLikeMatch[1]) {
return sshLikeMatch[1].toLowerCase();
}
return null;
}
private isGitHubUrl(value: string): boolean { private isGitHubUrl(value: string): boolean {
const normalized = value.toLowerCase(); const host = this.getHostFromGitUrl(value);
return normalized.includes('github.com') || normalized.includes('git@github.com:'); if (host) {
// Accept github.com and common www-prefixed variant.
return host === 'github.com' || host === 'www.github.com';
}
// Fallback for non-standard patterns like "github.com:owner/repo"
const normalized = value.trim().toLowerCase();
return normalized.startsWith('github.com:') || normalized.startsWith('ssh://github.com/');
} }
private isGitLabUrl(value: string): boolean { private isGitLabUrl(value: string): boolean {
const normalized = value.toLowerCase(); const host = this.getHostFromGitUrl(value);
return normalized.includes('gitlab.com') || normalized.includes('git@gitlab.com:') || normalized.includes('gitlab'); if (host) {
// Hosted GitLab
if (host === 'gitlab.com' || host === 'www.gitlab.com') {
return true;
}
// Self-hosted GitLab: many instances include "gitlab" in the hostname.
if (host.includes('gitlab')) {
return true;
}
}
// Fallback for non-standard patterns like "gitlab.com:owner/repo"
const normalized = value.trim().toLowerCase();
return normalized.startsWith('gitlab.com:') || normalized.startsWith('ssh://gitlab.com/');
} }
private isGiteaForgejoUrl(value: string): boolean { private isGiteaForgejoUrl(value: string): boolean {
const normalized = value.toLowerCase(); const host = this.getHostFromGitUrl(value);
if (host) {
if (host.includes('gitea') || host.includes('forgejo')) {
return true;
}
}
// Fallback: if we cannot parse a host, fall back to substring detection.
const normalized = value.trim().toLowerCase();
return normalized.includes('gitea') || normalized.includes('forgejo'); return normalized.includes('gitea') || normalized.includes('forgejo');
} }