Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions cmd/admin/handlers/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/jmpsec/osctrl/cmd/admin/sessions"
"github.com/jmpsec/osctrl/pkg/auditlog"
"github.com/jmpsec/osctrl/pkg/environments"
"github.com/jmpsec/osctrl/pkg/handlers"
"github.com/jmpsec/osctrl/pkg/nodes"
"github.com/jmpsec/osctrl/pkg/queries"
Expand Down Expand Up @@ -814,8 +815,13 @@ func (h *HandlersAdmin) EnvsPOSTHandler(w http.ResponseWriter, r *http.Request)
}
switch c.Action {
case "create":
// FIXME verify fields
if !h.Envs.Exists(c.Name) && c.Name != "" {
// Verify request fields
if !environments.VerifyEnvFilters(c.Name, c.Icon, c.Type, c.Hostname) {
adminErrorResponse(w, "invalid data", http.StatusInternalServerError, nil)
return
}
// Proceed with request data
if !h.Envs.Exists(c.Name) {
env := h.Envs.Empty(c.Name, c.Hostname)
env.Icon = c.Icon
env.Type = c.Type
Expand Down Expand Up @@ -859,6 +865,11 @@ func (h *HandlersAdmin) EnvsPOSTHandler(w http.ResponseWriter, r *http.Request)
return
}
case "delete":
// Verify request fields
if !environments.EnvNameFilter(c.Name) {
adminErrorResponse(w, "invalid environment name", http.StatusInternalServerError, nil)
return
}
if h.Envs.Exists(c.Name) {
if err := h.Envs.Delete(c.Name); err != nil {
adminErrorResponse(w, "error deleting environment", http.StatusInternalServerError, err)
Expand All @@ -867,6 +878,11 @@ func (h *HandlersAdmin) EnvsPOSTHandler(w http.ResponseWriter, r *http.Request)
}
adminOKResponse(w, "environment deleted successfully")
case "edit":
// Verify request fields
if !environments.EnvUUIDFilter(c.UUID) {
adminErrorResponse(w, "invalid environment UUID", http.StatusInternalServerError, nil)
return
}
if h.Envs.Exists(c.UUID) {
if err := h.Envs.UpdateHostname(c.UUID, c.Hostname); err != nil {
adminErrorResponse(w, "error updating hostname", http.StatusInternalServerError, err)
Expand Down
66 changes: 66 additions & 0 deletions pkg/environments/filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package environments

import "regexp"

const (
iconRegex string = `^[a-z0-9_-]+$`
nameRegex string = `^[a-zA-Z0-9_-]+$`
hostnameRegex string = `^[a-zA-Z0-9.\-]+$`
uuidRegex string = `^[a-z0-9-]+$`
envOsquery string = "osquery"
)

// Valid values for environment type in configuration
var validType = map[string]bool{
envOsquery: true,
}

// IconFilter - Helper to filter the icon name to prevent unsanitized input
func IconFilter(s string) bool {
// regex to only allow lowercase letters, numbers, dashes and underscores
re := regexp.MustCompile(iconRegex)
return re.MatchString(s)
Comment on lines +19 to +22
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex is compiled on every call to IconFilter, which is inefficient. Consider compiling the regex once at package initialization using a package-level variable or sync.Once to avoid repeated compilation overhead. The same issue applies to HostnameFilter, EnvNameFilter, and EnvUUIDFilter functions.

Copilot uses AI. Check for mistakes.
}

// EnvTypeFilter - Helper to filter the environment type to prevent unsanitized input
func EnvTypeFilter(s string) bool {
return validType[s]
}

// HostnameFilter - Helper to filter the hostname to prevent unsanitized input
func HostnameFilter(s string) bool {
// regex to only allow uppercase and lowercase letters, numbers, dashes and dots
re := regexp.MustCompile(hostnameRegex)
return re.MatchString(s)
}

// EnvNameFilter - Helper to filter the environment name to prevent unsanitized input
func EnvNameFilter(s string) bool {
// regex to only allow letters, numbers, dashes and underscores
re := regexp.MustCompile(nameRegex)
return re.MatchString(s)
}

// EnvUUIDFilter - Helper to filter the environment uuid to prevent unsanitized input
func EnvUUIDFilter(s string) bool {
// regex to only allow lowercase letters, numbers and dashes
re := regexp.MustCompile(uuidRegex)
return re.MatchString(s)
}

// VerifyEnvFilters to verify all filters for an environment
func VerifyEnvFilters(name, icon, sType, hostname string) bool {
if !EnvNameFilter(name) {
return false
}
if !IconFilter(icon) {
return false
}
if !EnvTypeFilter(sType) {
return false
}
if !HostnameFilter(hostname) {
return false
}
return true
}
Loading
Loading