{"title":"Unsafe tarfile Extraction via Path Traversal","language":"Python","severity":"Critical","cwe":"CWE-22","source_lines":[1],"flow_lines":[1,4,6,7,8],"sink_lines":[8],"vulnerable_code":"import tarfile\nimport os\n\ndef deploy_iot_firmware_package(firmware_archive, device_id):\n    deployment_dir = f\"/opt/iot/devices/{device_id}/firmware\"\n    os.makedirs(deployment_dir, exist_ok=True)\n    with tarfile.open(firmware_archive, 'r:gz') as tar_pkg:\n        for firmware_component in tar_pkg.getmembers():\n            tar_pkg.extract(firmware_component, path=deployment_dir)\n    return {\"status\": \"deployed\", \"location\": deployment_dir}","explanation":"The function accepts a firmware_archive path without validation and directly extracts all tar members without checking for path traversal sequences (../, absolute paths). An attacker can craft a malicious tar.gz with entries containing '../../../etc/cron.d/backdoor' to write files outside the intended deployment directory.","remediation":"The fix validates each tar member's resolved extraction path to ensure it remains within the intended deployment directory before extraction. It normalizes the path and checks that it starts with the deployment directory prefix, rejecting any entries containing path traversal sequences like '../' or absolute paths. Additionally, symbolic and hard links are validated to ensure they don't point outside the deployment directory.","secure_code":"import tarfile\nimport os\n\ndef deploy_iot_firmware_package(firmware_archive, device_id):\n    deployment_dir = f\"/opt/iot/devices/{device_id}/firmware\"\n    os.makedirs(deployment_dir, exist_ok=True)\n    with tarfile.open(firmware_archive, 'r:gz') as tar_pkg:\n        for firmware_component in tar_pkg.getmembers():\n            member_path = os.path.normpath(os.path.join(deployment_dir, firmware_component.name))\n            if not member_path.startswith(os.path.realpath(deployment_dir) + os.sep) and member_path != os.path.realpath(deployment_dir):\n                raise ValueError(f\"Attempted path traversal in firmware archive: {firmware_component.name}\")\n            if firmware_component.issym() or firmware_component.islnk():\n                link_target = os.path.normpath(os.path.join(deployment_dir, firmware_component.linkname))\n                if not link_target.startswith(os.path.realpath(deployment_dir) + os.sep):\n                    raise ValueError(f\"Symbolic/hard link points outside deployment directory: {firmware_component.name}\")\n            tar_pkg.extract(firmware_component, path=deployment_dir)\n    return {\"status\": \"deployed\", \"location\": deployment_dir}"}