fix github skill URL host validation

This commit is contained in:
lxowalle 2026-04-12 19:37:11 +08:00
parent 797802ee9b
commit 97aad37ac9
2 changed files with 51 additions and 0 deletions

View file

@ -168,6 +168,36 @@ func parseGitHubRefPathParts(repoURL *url.URL, githubBaseURL string) []string {
return parts[len(baseParts):] return parts[len(baseParts):]
} }
func isSupportedGitHubURL(repoURL *url.URL, githubBaseURL string) bool {
if repoURL == nil {
return false
}
if matchesGitHubWebBase(repoURL, "https://github.com") {
return true
}
trimmedBaseURL := strings.TrimSpace(githubBaseURL)
if trimmedBaseURL == "" {
return false
}
return matchesGitHubWebBase(repoURL, trimmedBaseURL)
}
func matchesGitHubWebBase(repoURL *url.URL, webBaseURL string) bool {
baseURL, err := url.Parse(strings.TrimSpace(webBaseURL))
if err != nil {
return false
}
if !strings.EqualFold(repoURL.Host, baseURL.Host) {
return false
}
basePath := strings.Trim(baseURL.Path, "/")
if basePath == "" {
return true
}
repoPath := strings.Trim(repoURL.Path, "/")
return repoPath == basePath || strings.HasPrefix(repoPath, basePath+"/")
}
func splitGitHubTreeOrBlobRefPath(parts []string, defaultRef string) (string, string) { func splitGitHubTreeOrBlobRefPath(parts []string, defaultRef string) (string, string) {
if len(parts) == 0 { if len(parts) == 0 {
return defaultRef, "" return defaultRef, ""
@ -216,6 +246,9 @@ func parseGitHubRefWithBaseURL(repo, githubBaseURL, defaultRef string) (GitHubRe
if err != nil { if err != nil {
return GitHubRef{}, fmt.Errorf("invalid URL: %w", err) return GitHubRef{}, fmt.Errorf("invalid URL: %w", err)
} }
if !isSupportedGitHubURL(u, githubBaseURL) {
return GitHubRef{}, fmt.Errorf("invalid GitHub URL host %q", u.Host)
}
parts := parseGitHubRefPathParts(u, githubBaseURL) parts := parseGitHubRefPathParts(u, githubBaseURL)
if len(parts) < 2 { if len(parts) < 2 {
return GitHubRef{}, fmt.Errorf("invalid GitHub URL") return GitHubRef{}, fmt.Errorf("invalid GitHub URL")

View file

@ -89,6 +89,12 @@ func TestParseGitHubRef(t *testing.T) {
wantRef: "main", wantRef: "main",
wantSubPath: "", wantSubPath: "",
}, },
{
name: "invalid non github host",
repo: "https://gitlab.com/sipeed/picoclaw/-/tree/main/skills/test",
wantErr: true,
wantErrContain: `invalid GitHub URL host "gitlab.com"`,
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -182,6 +188,18 @@ func TestParseGitHubRefWithBaseURL(t *testing.T) {
if ref.SubPath != ".agents/skills/pr-review" { if ref.SubPath != ".agents/skills/pr-review" {
t.Fatalf("subPath = %q, want .agents/skills/pr-review", ref.SubPath) t.Fatalf("subPath = %q, want .agents/skills/pr-review", ref.SubPath)
} }
_, err = parseGitHubRefWithBaseURL(
"https://gitlab.example.com/org/repo/-/tree/dev/skills/test",
"https://ghe.example.com/git",
"main",
)
if err == nil {
t.Fatal("parseGitHubRefWithBaseURL() error = nil, want invalid host error")
}
if !strings.Contains(err.Error(), `invalid GitHub URL host "gitlab.example.com"`) {
t.Fatalf("unexpected error = %v", err)
}
} }
func TestSkillInstallerResolveGitHubRefUsesDefaultBranch(t *testing.T) { func TestSkillInstallerResolveGitHubRefUsesDefaultBranch(t *testing.T) {