refactor(proxmox): add struct level validation for node configuration services and files

Add Validate() method to NodeConfig that implements the CustomValidator
interface. The method checks all services and files for invalid shell
metacharacters (&, $(), etc.) to prevent shell injection attacks.

Testing: Added validation_test.go with 6 table-driven test cases covering
valid inputs and various shell metacharacter injection attempts.
This commit is contained in:
yusing
2026-01-29 10:24:18 +08:00
parent 442e4a0972
commit b5946b34b8
2 changed files with 72 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"strings"
gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/pool"
)
@@ -25,6 +26,22 @@ type Node struct {
// statsScriptInitErrs *xsync.Map[int, error]
}
// Validate implements the serialization.CustomValidator interface.
func (n *NodeConfig) Validate() gperr.Error {
var errs gperr.Builder
for i, service := range n.Services {
if err := checkValidInput(service); err != nil {
errs.AddSubjectf(err, "services[%d]", i)
}
}
for i, file := range n.Files {
if err := checkValidInput(file); err != nil {
errs.AddSubjectf(err, "files[%d]", i)
}
}
return errs.Error()
}
var Nodes = pool.New[*Node]("proxmox_nodes")
func NewNode(client *Client, name, id string) *Node {

View File

@@ -0,0 +1,55 @@
package proxmox
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/yusing/godoxy/internal/serialization"
)
func TestValidateCommandArgs(t *testing.T) {
tests := []struct {
name string
yamlCfg string
wantErr bool
}{
{
name: "valid_services",
yamlCfg: `services: ["foo", "bar"]`,
wantErr: false,
},
{
name: "invalid_services",
yamlCfg: `services: ["foo", "bar & baz"]`,
wantErr: true,
},
{
name: "invalid_services_with_$(",
yamlCfg: `services: ["foo", "bar & $(echo 'hello')"]`,
wantErr: true,
},
{
name: "valid_files",
yamlCfg: `files: ["foo", "bar"]`,
wantErr: false,
},
{
name: "invalid_files",
yamlCfg: `files: ["foo", "bar & baz"]`,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var cfg NodeConfig
err := serialization.UnmarshalValidateYAML([]byte(tt.yamlCfg), &cfg)
if tt.wantErr {
require.Error(t, err)
require.ErrorContains(t, err, "input contains invalid characters")
} else {
require.NoError(t, err)
}
})
}
}