CVE-2023-30620 (published 2023-04-21T21:15Z)

mindsdb is a Machine Learning platform to help developers build AI solutions. In affected versions an unsafe extraction is being performed using `tarfile.extractall()` from a remotely retrieved tarball. Which may lead to the writing of the extracted files to an unintended location. Sometimes, the vulnerability is called a TarSlip or a ZipSlip variant. An attacker may leverage this vulnerability to overwrite any local file which the server process has access to. There is no risk of file exposure with this vulnerability. This issue has been addressed in release `23.2.1.0 `. Users are advised to upgrade. There are no known workarounds for this vulnerability.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N)

Weakness information:
cwe_id: CWE-22
cwe_name: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
description: 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.
extended_description: 
            Many file operations are intended to take place within a restricted directory. By using special elements such as ".." and "/" separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the "../" sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute pathnames such as "/usr/local/bin" to access unexpected files. This is referred to as absolute path traversal.
         
         

Fix information:
repo_url: https://github.com/mindsdb/mindsdb
commit_details: repo_url: https://github.com/mindsdb/mindsdb
author: zoran
author_date: 2023-02-16 20:31:12+01:00
msg: Use safe extract to prevent CVE-2007-4559 bug
repository: repo_url: https://github.com/mindsdb/mindsdb
repo_name: mindsdb/mindsdb
description: The platform for building AI from enterprise data
repo_language: Python
owner: mindsdb
file_changes: filename: file.py
change_type: ModificationType.MODIFY
diff: @@ -9,7 +9,7 @@ import multipart
 import requests
 
 from mindsdb.utilities import log
-from mindsdb.api.http.utils import http_error
+from mindsdb.api.http.utils import http_error, safe_extract
 from mindsdb.api.http.namespaces.configs.files import ns_conf
 from mindsdb.utilities.config import Config
 from mindsdb.utilities.context import context as ctx
@@ -134,7 +134,7 @@ class File(Resource):
                     f.extractall(temp_dir_path)
             elif lp.endswith('.tar.gz'):
                 with tarfile.open(file_path) as f:
-                    f.extractall(temp_dir_path)
+                    safe_extract(f, temp_dir_path)
             os.remove(file_path)
             files = os.listdir(temp_dir_path)
             if len(files) != 1:

programming_language: Python
filename: utils.py
change_type: ModificationType.MODIFY
diff: @@ -1,4 +1,5 @@
 import json
+import os
 
 from flask import Response
 
@@ -22,3 +23,17 @@ def http_error(status_code, title, detail=''):
             'Content-Type': 'application/problem+json'
         }
     )
+
+def __is_within_directory(directory, target):
+    abs_directory = os.path.abspath(directory)
+    abs_target = os.path.abspath(target)
+    prefix = os.path.commonprefix([abs_directory, abs_target])
+    return prefix == abs_directory
+
+def safe_extract(tar, path=".", members=None, *, numeric_owner=False):
+    for member in tar.getmembers():
+        member_path = os.path.join(path, member.name)
+        if not __is_within_directory(path, member_path):
+            raise Exception("Attempted Path Traversal in Tar File")
+    tar.extractall(path, members, numeric_owner) 
+

programming_language: Python