mirror of
https://github.com/lordmathis/llamactl.git
synced 2025-11-06 00:54:23 +00:00
Validate instance names to prevent injection attacks
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"llamactl/pkg/config"
|
"llamactl/pkg/config"
|
||||||
"llamactl/pkg/instance"
|
"llamactl/pkg/instance"
|
||||||
|
"llamactl/pkg/validation"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -140,9 +141,14 @@ func parseRemoteResponse(resp *http.Response, result any) error {
|
|||||||
|
|
||||||
// CreateInstance creates a new instance on a remote node.
|
// CreateInstance creates a new instance on a remote node.
|
||||||
func (rm *remoteManager) createInstance(ctx context.Context, node *config.NodeConfig, name string, opts *instance.Options) (*instance.Instance, error) {
|
func (rm *remoteManager) createInstance(ctx context.Context, node *config.NodeConfig, name string, opts *instance.Options) (*instance.Instance, error) {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
// This prevents SSRF and URL injection attacks
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
escapedName := url.PathEscape(name)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
||||||
|
|
||||||
@@ -161,8 +167,14 @@ func (rm *remoteManager) createInstance(ctx context.Context, node *config.NodeCo
|
|||||||
|
|
||||||
// GetInstance retrieves an instance by name from a remote node.
|
// GetInstance retrieves an instance by name from a remote node.
|
||||||
func (rm *remoteManager) getInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
func (rm *remoteManager) getInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
escapedName := url.PathEscape(name)
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
||||||
resp, err := rm.makeRemoteRequest(ctx, node, "GET", path, nil)
|
resp, err := rm.makeRemoteRequest(ctx, node, "GET", path, nil)
|
||||||
@@ -180,8 +192,14 @@ func (rm *remoteManager) getInstance(ctx context.Context, node *config.NodeConfi
|
|||||||
|
|
||||||
// UpdateInstance updates an existing instance on a remote node.
|
// UpdateInstance updates an existing instance on a remote node.
|
||||||
func (rm *remoteManager) updateInstance(ctx context.Context, node *config.NodeConfig, name string, opts *instance.Options) (*instance.Instance, error) {
|
func (rm *remoteManager) updateInstance(ctx context.Context, node *config.NodeConfig, name string, opts *instance.Options) (*instance.Instance, error) {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
escapedName := url.PathEscape(name)
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
||||||
|
|
||||||
@@ -200,8 +218,14 @@ func (rm *remoteManager) updateInstance(ctx context.Context, node *config.NodeCo
|
|||||||
|
|
||||||
// DeleteInstance deletes an instance from a remote node.
|
// DeleteInstance deletes an instance from a remote node.
|
||||||
func (rm *remoteManager) deleteInstance(ctx context.Context, node *config.NodeConfig, name string) error {
|
func (rm *remoteManager) deleteInstance(ctx context.Context, node *config.NodeConfig, name string) error {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
escapedName := url.PathEscape(name)
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
path := fmt.Sprintf("%s%s/", apiBasePath, escapedName)
|
||||||
resp, err := rm.makeRemoteRequest(ctx, node, "DELETE", path, nil)
|
resp, err := rm.makeRemoteRequest(ctx, node, "DELETE", path, nil)
|
||||||
@@ -214,8 +238,14 @@ func (rm *remoteManager) deleteInstance(ctx context.Context, node *config.NodeCo
|
|||||||
|
|
||||||
// StartInstance starts an instance on a remote node.
|
// StartInstance starts an instance on a remote node.
|
||||||
func (rm *remoteManager) startInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
func (rm *remoteManager) startInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
escapedName := url.PathEscape(name)
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/start", apiBasePath, escapedName)
|
path := fmt.Sprintf("%s%s/start", apiBasePath, escapedName)
|
||||||
resp, err := rm.makeRemoteRequest(ctx, node, "POST", path, nil)
|
resp, err := rm.makeRemoteRequest(ctx, node, "POST", path, nil)
|
||||||
@@ -233,8 +263,14 @@ func (rm *remoteManager) startInstance(ctx context.Context, node *config.NodeCon
|
|||||||
|
|
||||||
// StopInstance stops an instance on a remote node.
|
// StopInstance stops an instance on a remote node.
|
||||||
func (rm *remoteManager) stopInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
func (rm *remoteManager) stopInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
escapedName := url.PathEscape(name)
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/stop", apiBasePath, escapedName)
|
path := fmt.Sprintf("%s%s/stop", apiBasePath, escapedName)
|
||||||
resp, err := rm.makeRemoteRequest(ctx, node, "POST", path, nil)
|
resp, err := rm.makeRemoteRequest(ctx, node, "POST", path, nil)
|
||||||
@@ -252,8 +288,14 @@ func (rm *remoteManager) stopInstance(ctx context.Context, node *config.NodeConf
|
|||||||
|
|
||||||
// RestartInstance restarts an instance on a remote node.
|
// RestartInstance restarts an instance on a remote node.
|
||||||
func (rm *remoteManager) restartInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
func (rm *remoteManager) restartInstance(ctx context.Context, node *config.NodeConfig, name string) (*instance.Instance, error) {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
escapedName := url.PathEscape(name)
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/restart", apiBasePath, escapedName)
|
path := fmt.Sprintf("%s%s/restart", apiBasePath, escapedName)
|
||||||
resp, err := rm.makeRemoteRequest(ctx, node, "POST", path, nil)
|
resp, err := rm.makeRemoteRequest(ctx, node, "POST", path, nil)
|
||||||
@@ -271,8 +313,14 @@ func (rm *remoteManager) restartInstance(ctx context.Context, node *config.NodeC
|
|||||||
|
|
||||||
// GetInstanceLogs retrieves logs for an instance from a remote node.
|
// GetInstanceLogs retrieves logs for an instance from a remote node.
|
||||||
func (rm *remoteManager) getInstanceLogs(ctx context.Context, node *config.NodeConfig, name string, numLines int) (string, error) {
|
func (rm *remoteManager) getInstanceLogs(ctx context.Context, node *config.NodeConfig, name string, numLines int) (string, error) {
|
||||||
// URL-encode the instance name to safely include it in the URL path
|
// Validate instance name to prevent injection attacks
|
||||||
escapedName := url.PathEscape(name)
|
validatedName, err := validation.ValidateInstanceName(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL-encode the validated instance name to safely include it in the URL path
|
||||||
|
escapedName := url.PathEscape(validatedName)
|
||||||
|
|
||||||
path := fmt.Sprintf("%s%s/logs?lines=%d", apiBasePath, escapedName, numLines)
|
path := fmt.Sprintf("%s%s/logs?lines=%d", apiBasePath, escapedName, numLines)
|
||||||
resp, err := rm.makeRemoteRequest(ctx, node, "GET", path, nil)
|
resp, err := rm.makeRemoteRequest(ctx, node, "GET", path, nil)
|
||||||
|
|||||||
Reference in New Issue
Block a user