CVE-2024-6095 (Go, published 2024-07-06T18:15Z)
Description: value: A vulnerability in the /models/apply endpoint of mudler/localai versions 2.15.0 allows for Server-Side Request Forgery (SSRF) and partial Local File Inclusion (LFI). The endpoint supports both http(s):// and file:// schemes, where the latter can lead to LFI. However, the output is limited due to the length of the error message. This vulnerability can be exploited by an attacker with network access to the LocalAI instance, potentially allowing unauthorized access to internal HTTP(s) servers and partial reading of local files. The issue is fixed in version 2.17.
Severity: nan (CVSS v3 base score: 5.8)
Weakness: CWE-918 \u2014 Server-Side Request Forgery (SSRF)
The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
Repository: https://github.com/mudler/localai
Files changed:
core/http/app_test.go
core/services/gallery.go
embedded/embedded.go
pkg/downloader/uri.go
pkg/downloader/uri_test.go
pkg/gallery/gallery.go
pkg/gallery/models.go
pkg/gallery/request_test.go
pkg/startup/model_preload.go
Commit message: fix: `pkg/downloader` should respect basePath for `file://` urls (#2481)

* pass basePath down to pkg/downloader

Signed-off-by: Dave Lee <dave@gray101.com>

* enforce

Signed-off-by: Dave Lee <dave@gray101.com>

---------

Signed-off-by: Dave Lee <dave@gray101.com>

Vulnerable code:
	downloader.GetURI(url, func(url string, i []byte) error {
	config, err := gallery.GetGalleryConfigFromURL(req.URL)
func GetRemoteLibraryShorteners(url string) (map[string]string, error) {
	err := downloader.GetURI(url, func(_ string, i []byte) error {
func GetURI(url string, f func(url string, i []byte) error) error {
				GetURI("github:go-skynet/model-gallery/gpt4all-j.yaml", func(url string, i []byte) error {
				GetURI("github:go-skynet/model-gallery/gpt4all-j.yaml@main", func(url string, i []byte) error {
				GetURI("https://raw.githubusercontent.com/go-skynet/model-gallery/main/gpt4all-j.yaml", func(url string, i []byte) error {
			config, err = GetGalleryConfigFromURL(model.URL)
func findGalleryURLFromReferenceURL(url string) (string, error) {
	err := downloader.GetURI(url, func(url string, d []byte) error {
		gallery.URL, err = findGalleryURLFromReferenceURL(gallery.URL)
	err := downloader.GetURI(gallery.URL, func(url string, d []byte) error {
func GetGalleryConfigFromURL(url string) (Config, error) {
	err := downloader.GetURI(url, func(url string, d []byte) error {
			e, err := GetGalleryConfigFromURL(req.URL)
			lib, err := embedded.GetRemoteLibraryShorteners(modelLibraryURL)

Fixed code:
	// TODO: No tests currently seem to exercise file:// urls. Fix?
	downloader.GetURI(url, "", func(url string, i []byte) error {
	config, err := gallery.GetGalleryConfigFromURL(req.URL, modelPath)
func GetRemoteLibraryShorteners(url string, basePath string) (map[string]string, error) {
	err := downloader.GetURI(url, basePath, func(_ string, i []byte) error {
func GetURI(url string, basePath string, f func(url string, i []byte) error) error {
		// Check if the local file is rooted in basePath
		err = utils.VerifyPath(resolvedFile, basePath)
		if err != nil {
			return err
		}
				GetURI("github:go-skynet/model-gallery/gpt4all-j.yaml", "", func(url string, i []byte) error {
				GetURI("github:go-skynet/model-gallery/gpt4all-j.yaml@main", "", func(url string, i []byte) error {
				GetURI("https://raw.githubusercontent.com/go-skynet/model-gallery/main/gpt4all-j.yaml", "", func(url string, i []byte) error {
			config, err = GetGalleryConfigFromURL(model.URL, basePath)
func findGalleryURLFromReferenceURL(url string, basePath string) (string, error) {
	err := downloader.GetURI(url, basePath, func(url string, d []byte) error {
		gallery.URL, err = findGalleryURLFromReferenceURL(gallery.URL, basePath)
	err := downloader.GetURI(gallery.URL, basePath, func(url string, d []byte) error {
func GetGalleryConfigFromURL(url string, basePath string) (Config, error) {
	err := downloader.GetURI(url, basePath, func(url string, d []byte) error {
			e, err := GetGalleryConfigFromURL(req.URL, "")
			lib, err := embedded.GetRemoteLibraryShorteners(modelLibraryURL, modelPath)