From a96477164d783b13ede38194c03bff47709c12b3 Mon Sep 17 00:00:00 2001 From: Aditya <60684641+0x0elliot@users.noreply.github.com> Date: Wed, 22 Jul 2026 05:30:57 +0530 Subject: [PATCH] fix/feat: sanitize query params in GetOrborusDownloadCommand to prevent script injection --- cloudSync.go | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/cloudSync.go b/cloudSync.go index 9578099b..01230df8 100755 --- a/cloudSync.go +++ b/cloudSync.go @@ -19,6 +19,7 @@ import ( "strconv" "sync" "encoding/base64" + "regexp" //"github.com/algolia/algoliasearch-client-go/v3/algolia/opt" "github.com/algolia/algoliasearch-client-go/v3/algolia/search" @@ -3311,6 +3312,24 @@ func HandleSensorDatastoreUpdate(orborusDetails OrborusStats) { } } +var shellUnsafeRe = regexp.MustCompile(`[;<>&|` + "\\$`" + `\\'"(){}\x00-\x1f\x7f<>]`) + +func sanitizeShellParam(s string) string { + return strings.TrimSpace(shellUnsafeRe.ReplaceAllString(s, "")) +} + +func validateShellURL(raw string) (string, bool) { + u, err := url.Parse(raw) + if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" { + return "", false + } + cleaned := u.Scheme + "://" + u.Host + u.Path + if shellUnsafeRe.MatchString(cleaned) { + return "", false + } + return cleaned, true +} + // Download handler for Orborus agent installation script. This is used in the "Assets" page for Orborus, and can be used by customers to easily install Orborus on their hosts. It returns a bash script that can be run on the target host to install Orborus with the correct configuration. func GetOrborusDownloadCommand(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") @@ -3353,22 +3372,33 @@ func GetOrborusDownloadCommand(w http.ResponseWriter, r *http.Request) { } if v := q.Get("base_url"); v != "" { - c.BaseURL = v + if cleaned, ok := validateShellURL(v); ok { + c.BaseURL = cleaned + } else { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "invalid base_url: must be a valid http or https URL") + return + } } if v := q.Get("queue"); v != "" { - c.Queue = v + c.Queue = sanitizeShellParam(v) } if v := q.Get("auth"); v != "" { - c.Auth = v + c.Auth = sanitizeShellParam(v) } if v := q.Get("org_id"); v != "" { + if !isValidUUID(v) { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "invalid org_id: must be a valid UUID") + return + } c.OrgID = v } if v := q.Get("response_actions"); v != "" { - c.ResponseActions = v + c.ResponseActions = sanitizeShellParam(v) } if v := q.Get("log_forwarding"); v != "" { - c.LogForwarding = v + c.LogForwarding = sanitizeShellParam(v) } if v := q.Get("software_list_enabled"); v != "" { c.SoftwareListEnabled = v == "true" @@ -3383,9 +3413,8 @@ func GetOrborusDownloadCommand(w http.ResponseWriter, r *http.Request) { c.AsRoot = v != "false" } - // Check the "AUTH" header for a secret value to allow overriding the config (for security) if authHeader := r.Header.Get("AUTH"); authHeader != "" { - c.Auth = authHeader + c.Auth = sanitizeShellParam(authHeader) } // Quite untested.