Use allowlisted host-agent filenames in router

This commit is contained in:
rcourtman 2026-03-31 09:40:54 +01:00
parent c50342abe7
commit 6a5a5ee615
2 changed files with 46 additions and 26 deletions

View file

@ -53,7 +53,7 @@ var requiredHostAgentBinaries = []HostAgentBinary{
}
var supportedHostAgentTargets = []HostAgentBinary{
{Platform: "freebsd", Arch: "amd64"},
{Platform: "freebsd", Arch: "amd64", Filenames: []string{"pulse-host-agent-freebsd-amd64"}},
}
// IsSupportedHostAgentPlatform reports whether platform is one of the release-supported host-agent platforms.
@ -86,6 +86,41 @@ func IsSupportedHostAgentTarget(platform, arch string) bool {
return false
}
// HostAgentCandidateFilenames returns the fixed allowlisted filenames for a
// requested host-agent target. This avoids deriving filenames directly from
// untrusted request parameters in higher-level handlers.
func HostAgentCandidateFilenames(platform, arch string) []string {
if platform == "" {
return []string{"pulse-host-agent"}
}
if arch == "" {
switch platform {
case "linux":
return []string{"pulse-host-agent-linux"}
case "darwin":
return []string{"pulse-host-agent-darwin"}
case "windows":
return []string{"pulse-host-agent-windows", "pulse-host-agent-windows.exe"}
case "freebsd":
return []string{"pulse-host-agent-freebsd"}
default:
return nil
}
}
for _, binary := range requiredHostAgentBinaries {
if binary.Platform == platform && binary.Arch == arch {
return append([]string(nil), binary.Filenames...)
}
}
for _, binary := range supportedHostAgentTargets {
if binary.Platform == platform && binary.Arch == arch {
return append([]string(nil), binary.Filenames...)
}
}
return nil
}
var downloadMu sync.Mutex
var (

View file

@ -7228,34 +7228,19 @@ func (r *Router) tryServeHostAgentBinary(w http.ResponseWriter, req *http.Reques
}
func hostAgentSearchCandidates(platformParam, archParam string) []string {
searchPaths := make([]string, 0, 12)
strictMode := platformParam != "" && archParam != ""
if strictMode {
searchPaths = append(searchPaths,
filepath.Join(pulseBinDir(), fmt.Sprintf("pulse-host-agent-%s-%s", platformParam, archParam)),
filepath.Join("/opt/pulse", fmt.Sprintf("pulse-host-agent-%s-%s", platformParam, archParam)),
filepath.Join("/app", fmt.Sprintf("pulse-host-agent-%s-%s", platformParam, archParam)),
)
filenames := agentbinaries.HostAgentCandidateFilenames(platformParam, archParam)
if len(filenames) == 0 {
return nil
}
if platformParam != "" && !strictMode {
searchPaths = append(searchPaths,
filepath.Join(pulseBinDir(), "pulse-host-agent-"+platformParam),
filepath.Join("/opt/pulse", "pulse-host-agent-"+platformParam),
filepath.Join("/app", "pulse-host-agent-"+platformParam),
)
dirs := []string{pulseBinDir(), "/opt/pulse", "/app"}
searchPaths := make([]string, 0, len(dirs)*len(filenames))
for _, dir := range dirs {
for _, filename := range filenames {
searchPaths = append(searchPaths, filepath.Join(dir, filename))
}
}
if !strictMode && platformParam == "" {
searchPaths = append(searchPaths,
filepath.Join(pulseBinDir(), "pulse-host-agent"),
"/opt/pulse/pulse-host-agent",
filepath.Join("/app", "pulse-host-agent"),
)
}
return searchPaths
return dedupeStrings(searchPaths)
}
func dedupeStrings(values []string) []string {