Skip to content
Permalink
Browse files
🔒️ Close a sanity check hole in language packs
A language pack containing a directory traversing
symlink could be uploaded. Upon backup creation, the
symlink would then lead to inclusion of whatever it
was pointing to in the resulting backup. This could
be used by an attacker with admin permissions to extract
information from the server.
  • Loading branch information
foosel committed Aug 31, 2022
1 parent ef95ef1 commit 3cca3a43f3d085e9bbe5a5840c8255bb1b5d052e
Showing 1 changed file with 16 additions and 4 deletions.
@@ -174,7 +174,8 @@ def deleteInstalledLanguagePack(locale, pack):
def _unpack_uploaded_zipfile(path, target):
with zipfile.ZipFile(path, "r") as zip:
# sanity check
map(_validate_archive_name, zip.namelist())
for info in zip.infolist():
_validate_zip_info(info, target)

# unpack everything
zip.extractall(target)
@@ -183,16 +184,27 @@ def _unpack_uploaded_zipfile(path, target):
def _unpack_uploaded_tarball(path, target):
with tarfile.open(path, "r") as tar:
# sanity check
map(_validate_archive_name, tar.getmembers())
for info in tar.getmembers():
_validate_tar_info(info, target)

# unpack everything
tar.extractall(target)


def _validate_archive_name(name):
if name.startswith("/") or ".." in name:
def _validate_archive_name(name, target):
if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep):
raise InvalidLanguagePack(f"Provided language pack contains invalid name {name}")


def _validate_zip_info(info, target):
_validate_archive_name(info.filename, target)


def _validate_tar_info(info, target):
_validate_archive_name(info.name, target)
if not (info.isfile() or info.isdir()):
raise InvalidLanguagePack("Provided language pack contains invalid file type")


class InvalidLanguagePack(Exception):
pass

0 comments on commit 3cca3a4

Please sign in to comment.