diff --git a/src/mvt/android/modules/bugreport/base.py b/src/mvt/android/modules/bugreport/base.py index 70ede77..519ea70 100644 --- a/src/mvt/android/modules/bugreport/base.py +++ b/src/mvt/android/modules/bugreport/base.py @@ -6,6 +6,7 @@ import datetime import fnmatch import logging import os +from pathlib import Path from typing import List, Optional from zipfile import ZipFile @@ -70,7 +71,10 @@ class BugReportModule(MVTModule): else: if not self.extract_path: raise ValueError("extract_path is not set") - handle = open(os.path.join(self.extract_path, file_path), "rb") + joined = os.path.join(self.extract_path, file_path) + if not Path(joined).resolve().is_relative_to(Path(self.extract_path).resolve()): + raise ValueError("unsafe file_path") + handle = open(joined, "rb") data = handle.read() handle.close() diff --git a/src/mvt/ios/decrypt.py b/src/mvt/ios/decrypt.py index 620ee7e..ceac3e2 100644 --- a/src/mvt/ios/decrypt.py +++ b/src/mvt/ios/decrypt.py @@ -11,6 +11,7 @@ import os import os.path import shutil import sqlite3 +from pathlib import Path from typing import Optional from iOSbackup import iOSbackup @@ -96,6 +97,9 @@ class DecryptBackup: # This may be a partial backup. Skip files from the manifest # which do not exist locally. source_file_path = os.path.join(self.backup_path, file_id[0:2], file_id) + if not Path(source_file_path).resolve().is_relative_to(Path(self.backup_path).resolve()): + log.warning("Skipping unsafe file_id: %r", file_id) + continue if not os.path.exists(source_file_path): log.debug( "Skipping file %s. File not found in encrypted backup directory.", @@ -104,6 +108,9 @@ class DecryptBackup: continue item_folder = os.path.join(self.dest_path, file_id[0:2]) # type: ignore[arg-type] + if not Path(os.path.join(item_folder, file_id)).resolve().is_relative_to(Path(self.dest_path).resolve()): + log.warning("Skipping unsafe file_id: %r", file_id) + continue if not os.path.exists(item_folder): os.makedirs(item_folder) diff --git a/src/mvt/ios/modules/base.py b/src/mvt/ios/modules/base.py index 3ff5509..58ea22b 100644 --- a/src/mvt/ios/modules/base.py +++ b/src/mvt/ios/modules/base.py @@ -9,6 +9,7 @@ import os import shutil import sqlite3 import subprocess +from pathlib import Path from typing import Iterator, Optional, Union from mvt.common.module import ( @@ -165,6 +166,8 @@ class IOSExtraction(MVTModule): if not self.target_path: return None file_path = os.path.join(self.target_path, file_id[0:2], file_id) + if not Path(file_path).resolve().is_relative_to(Path(self.target_path).resolve()): + return None if os.path.exists(file_path): return file_path