diff --git a/cmd/urunc/create.go b/cmd/urunc/create.go index 8911eae2..2ae3635e 100644 --- a/cmd/urunc/create.go +++ b/cmd/urunc/create.go @@ -94,6 +94,9 @@ func createUnikontainer(cmd *cli.Command, uruncCfg *unikontainers.UruncConfig) ( err = fmt.Errorf("container id cannot be empty") return err } + if err = validateID(containerID); err != nil { + return err + } metrics.SetLoggerContainerID(containerID) metrics.Capture(m.TS00) diff --git a/cmd/urunc/utils.go b/cmd/urunc/utils.go index 2773d765..e2646548 100644 --- a/cmd/urunc/utils.go +++ b/cmd/urunc/utils.go @@ -21,6 +21,7 @@ import ( "os" "os/exec" "syscall" + "path/filepath" "github.com/moby/sys/userns" "github.com/sirupsen/logrus" @@ -37,6 +38,7 @@ const ( ) var ErrEmptyContainerID = errors.New("container ID can not be empty") +var ErrInvalidID = errors.New("invalid container id format") // checkArgs checks the number of arguments provided in the command-line context // against the expected number, based on the specified checkType. @@ -72,6 +74,9 @@ func getUnikontainer(cmd *cli.Command) (*unikontainers.Unikontainer, error) { if containerID == "" { return nil, ErrEmptyContainerID } + if err := validateID(containerID); err != nil { + return nil, err + } // We have already made sure in main.go that root is not nil rootDir := cmd.String("root") @@ -160,3 +165,33 @@ func prepareXDGRuntimeDir(root string) error { } return nil } + +// validateID validates the given ID string against the allowed characters. +func validateID(id string) error { + if len(id) < 1 { + return ErrInvalidID + } + + // Allowed characters: 0-9 A-Z a-z _ + - . + for i := range len(id) { + c := id[i] + switch { + case c >= 'a' && c <= 'z': + case c >= 'A' && c <= 'Z': + case c >= '0' && c <= '9': + case c == '_': + case c == '+': + case c == '-': + case c == '.': + default: + return ErrInvalidID + } + + } + + if string(os.PathSeparator)+id != filepath.Clean(string(os.PathSeparator)+id) { + return ErrInvalidID + } + + return nil +}