CVE-2024-5182 (Other, published 2024-06-20T00:15Z)
Description: value: A path traversal vulnerability exists in mudler/localai version 2.14.0, where an attacker can exploit the `model` parameter during the model deletion process to delete arbitrary files. Specifically, by crafting a request with a manipulated `model` parameter, an attacker can traverse the directory structure and target files outside of the intended directory, leading to the deletion of sensitive data. This vulnerability is due to insufficient input validation and sanitization of the `model` parameter.
Severity: nan (CVSS v3 base score: )
Weakness: CWE-22 \u2014 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Repository: https://github.com/mudler/localai
Files changed:
.github/workflows/generate_grpc_cache.yaml
.github/workflows/image_build.yml
.github/workflows/release.yaml
.github/workflows/test-extra.yml
.github/workflows/test.yml
backend/python/autogptq/requirements.txt
backend/python/bark/requirements.txt
backend/python/common/template/requirements.txt
backend/python/coqui/requirements.txt
backend/python/diffusers/requirements.txt
backend/python/exllama/requirements.txt
backend/python/exllama2/requirements.txt
backend/python/mamba/requirements.txt
backend/python/openvoice/requirements-intel.txt
backend/python/openvoice/requirements.txt
backend/python/parler-tts/requirements.txt
backend/python/rerankers/requirements.txt
backend/python/sentencetransformers/requirements.txt
backend/python/transformers-musicgen/requirements.txt
backend/python/transformers/requirements.txt
backend/python/vall-e-x/requirements.txt
backend/python/vllm/requirements.txt
core/config/backend_config.go
core/config/backend_config_loader.go
core/config/backend_config_test.go
core/config/config_suite_test.go
core/config/config_test.go
pkg/model/process.go
Commit message: dependencies(grpcio): bump to fix CI issues (#2362)

feat(grpcio): bump to fix CI issues

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

Vulnerable code:
            GRPC_VERSION=v1.63.0
            GRPC_VERSION=v1.63.0
  GRPC_VERSION: v1.63.0
          pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
  #         pip install --user grpcio-tools==1.63.0
  #         pip install --user grpcio-tools==1.63.0
  #         pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
          pip install --user grpcio-tools==1.63.0
  GRPC_VERSION: v1.63.0
          pip install --user grpcio-tools==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
grpcio==1.63.0
		cm.configs[cc.Name] = *cc
	cl.configs[c.Name] = *c
		return err
		if err == nil {
			opts := NewApplicationConfig()
			err := cm.LoadBackendConfigsFromPath(opts.ModelPath)
			// config should includes gpt4all models's api.config
			Expect(cm.ListBackendConfigs()).To(ContainElements("gpt4all"))

			// config should includes gpt2 models's api.config
			Expect(cm.ListBackendConfigs()).To(ContainElements("gpt4all-2"))
	if err := ml.grpcProcesses[s].Stop(); err != nil {
		return err

Fixed code:
            GRPC_VERSION=v1.64.0
            GRPC_VERSION=v1.64.0
  GRPC_VERSION: v1.64.0
          pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
  #         pip install --user grpcio-tools==1.64.0
  #         pip install --user grpcio-tools==1.64.0
  #         pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
          pip install --user grpcio-tools==1.64.0
  GRPC_VERSION: v1.64.0
          pip install --user grpcio-tools==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
grpcio==1.64.0
	"regexp"
	"strings"

func (c *BackendConfig) Validate() bool {
	// Simple validation to make sure the model can be correctly loaded
	for _, n := range []string{c.Backend, c.Model} {
		if strings.HasPrefix(n, string(os.PathSeparator)) ||
			strings.Contains(n, "..") {
			return false
		}
	}

	if c.Name == "" {
		return false
	}

	if c.Backend != "" {
		// a regex that checks that is a string name with no special characters, except '-' and '_'
		re := regexp.MustCompile(`^[a-zA-Z0-9-_]+$`)
		return re.MatchString(c.Backend)
	}

	return true
}
		if cc.Validate() {
			cm.configs[cc.Name] = *cc
		}
	if c.Validate() {
		cl.configs[c.Name] = *c
	} else {
		return fmt.Errorf("config is not valid")
	}

		return fmt.Errorf("cannot read directory '%s': %w", path, err)
		if err != nil {
			log.Error().Err(err).Msgf("cannot read config file: %s", file.Name())
			continue
		}
		if c.Validate() {
		} else {
			log.Error().Err(err).Msgf("config is not valid")
package config_test

import (
	"io"
	"net/http"
	"os"

	. "github.com/go-skynet/LocalAI/core/config"

	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
)

var _ = Describe("Test cases for config related functions", func() {
	Context("Test Read configuration functions", func() {
		It("Test Validate", func() {
			tmp, err := os.CreateTemp("", "config.yaml")
			Expect(err).To(BeNil())
			defer os.Remove(tmp.Name())
			_, err = tmp.WriteString(
				`backend: "foo-bar"
parameters:
  model: "foo-bar"`)
			Expect(err).ToNot(HaveOccurred())
			config, err := ReadBackendConfig(tmp.Name())
			Expect(err).To(BeNil())
			Expect(config).ToNot(BeNil())
			Expect(config.Validate()).To(BeFalse())
		})
		It("Test Validate", func() {
			tmp, err := os.CreateTemp("", "config.yaml")
			Expect(err).To(BeNil())
			defer os.Remove(tmp.Name())
			_, err = tmp.WriteString(
				`name: bar-baz
backend: "foo-bar"
parameters:
  model: "foo-bar"`)
			Expect(err).ToNot(HaveOccurred())
			config, err := ReadBackendConfig(tmp.Name())
			Expect(err).To(BeNil())
			Expect(config).ToNot(BeNil())
			// two configs in config.yaml
			Expect(config.Name).To(Equal("bar-baz"))
			Expect(config.Validate()).To(BeTrue())

			// download https://raw.githubusercontent.com/mudler/LocalAI/master/embedded/models/hermes-2-pro-mistral.yaml
			httpClient := http.Client{}
			resp, err := httpClient.Get("https://raw.githubusercontent.com/mudler/LocalAI/master/embedded/models/hermes-2-pro-mistral.yaml")
			Expect(err).To(BeNil())
			defer resp.Body.Close()
			tmp, err = os.CreateTemp("", "config.yaml")
			Expect(err).To(BeNil())
			defer os.Remove(tmp.Name())
			_, err = io.Copy(tmp, resp.Body)
			Expect(err).To(BeNil())
			config, err = ReadBackendConfig(tmp.Name())
			Expect(err).To(BeNil())
			Expect(config).ToNot(BeNil())
			// two configs in config.yaml
			Expect(config.Name).To(Equal("hermes-2-pro-mistral"))
			Expect(config.Validate()).To(BeTrue())
		})
	})
})
package config_test

import (
	"testing"

	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
)

func TestConfig(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Config test suite")
}
			err := cm.LoadBackendConfigsFromPath(os.Getenv("MODELS_PATH"))
			Expect(cm.ListBackendConfigs()).To(ContainElements("code-search-ada-code-001"))
	if _, exists := ml.grpcProcesses[s]; exists {
		if err := ml.grpcProcesses[s].Stop(); err != nil {
			return err
		}