{"record":{"id":"cd95714312e2f802","repo":"invoke-ai/InvokeAI","slug":"absolute-paths-not-allowed-in-subfolder-path","errorCode":null,"errorMessage":"Absolute paths not allowed in subfolder path","messagePattern":"Absolute paths not allowed in subfolder path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"invokeai/app/services/image_files/image_files_disk.py","lineNumber":285,"sourceCode":"\n        # Ensure the image path is within the base folder to prevent directory traversal\n        resolved_base = base_folder.resolve()\n        resolved_image_path = image_path.resolve()\n\n        if not resolved_image_path.is_relative_to(resolved_base):\n            raise ValueError(\"Image path outside outputs folder, potential directory traversal detected\")\n\n        return resolved_image_path\n\n    @staticmethod\n    def _validate_subfolder(subfolder: str) -> None:\n        \"\"\"Validates a subfolder path to prevent directory traversal while allowing controlled subdirectories.\"\"\"\n        if not subfolder:\n            return\n        if \"\\\\\" in subfolder:\n            raise ValueError(\"Backslashes not allowed in subfolder path\")\n        if subfolder.startswith(\"/\"):\n            raise ValueError(\"Absolute paths not allowed in subfolder path\")\n        parts = subfolder.split(\"/\")\n        for part in parts:\n            if part == \"..\":\n                raise ValueError(\"Parent directory references not allowed in subfolder path\")\n            if part == \"\":\n                raise ValueError(\"Empty path segments not allowed in subfolder path\")\n\n    def validate_path(self, path: Union[str, Path]) -> bool:\n        \"\"\"Validates the path given for an image or thumbnail.\"\"\"\n        path = path if isinstance(path, Path) else Path(path)\n        return path.exists()\n\n    def get_workflow(self, image_name: str, image_subfolder: str = \"\") -> str | None:\n        image = self.get(image_name, image_subfolder=image_subfolder)\n        workflow = image.info.get(\"invokeai_workflow\", None)\n        if isinstance(workflow, str):\n            return workflow\n        return None","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/image_files/image_files_disk.py#L267-L303","documentation":"_validate_subfolder rejects subfolders that start with '/', i.e. absolute paths, to prevent escaping the outputs folder entirely. Only relative subfolder names under the base folder are allowed.","triggerScenarios":"Passing image_subfolder='/etc' or '/tmp/x' to get/save; deriving the subfolder from an absolute path returned by a file dialog.","commonSituations":"Storing absolute paths in board metadata; users pasting absolute paths into configuration; code that assumes subfolder can be absolute.","solutions":["Convert to relative: strip the known base prefix before calling","Use only bare relative names like '2024/08'","Validate at the boundary that subfolder.startswith('/') is false and reject"],"exampleFix":"// before\nsub = '/home/user/outputs/2024'\n// after\nsub = '2024'  # or sub = os.path.relpath(p, base).replace('\\\\', '/')","handlingStrategy":"validation","validationCode":"from pathlib import PurePosixPath\ndef is_relative_subfolder(s: str) -> bool:\n    return bool(s) and not s.startswith('/') and '\\\\' not in s\nif not is_relative_subfolder(sub): raise ValueError('subfolder must be relative, /-separated')","typeGuard":"def is_relative_subfolder(s: object) -> bool:\n    return isinstance(s, str) and s != '' and not s.startswith('/')","tryCatchPattern":"try:\n    service.get(name, image_subfolder=subfolder)\nexcept ValueError as e:\n    if 'Absolute paths' in str(e):\n        sub = posixpath.relpath(sub, base) if sub.startswith(base) else ''\n        service.get(name, image_subfolder=sub)","preventionTips":["Store only relative subfolder names in configs and metadata","Convert file-dialog results to paths relative to the outputs folder","Reject absolute paths in user-facing board/subfolder inputs"],"tags":["validation","path","absolute-path"],"backgroundTag":"invalid-path-separator","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}