{"record":{"id":"40a0972a1163f806","repo":"pypa/pip","slug":"invalid-member-in-the-tar-file","errorCode":null,"errorMessage":"Invalid member in the tar file {}: {}","messagePattern":"Invalid member in the tar file (.+?): (.+?)","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"critical","filePath":"src/pip/_internal/utils/unpacking.py","lineNumber":238,"sourceCode":"                    except tarfile.LinkOutsideDestinationError:\n                        if sys.version_info[:3] in {\n                            (3, 9, 17),\n                            (3, 10, 12),\n                            (3, 11, 4),\n                        }:\n                            # The tarfile filter in specific Python versions\n                            # raises LinkOutsideDestinationError on valid input\n                            # (https://github.com/python/cpython/issues/107845)\n                            # Ignore the error there, but do use the\n                            # more lax `tar_filter`\n                            member = tarfile.tar_filter(member, location)\n                        else:\n                            raise\n                except tarfile.TarError as exc:\n                    message = \"Invalid member in the tar file {}: {}\"\n                    # Filter error messages mention the member name.\n                    # No need to add it here.\n                    raise InstallationError(\n                        message.format(\n                            filename,\n                            exc,\n                        )\n                    )\n                if member.isfile() and orig_mode & 0o111:\n                    member.mode = default_mode_plus_executable\n                else:\n                    # See PEP 706 note above.\n                    # The PEP changed this from `int` to `Optional[int]`,\n                    # where None means \"use the default\". Mypy doesn't\n                    # know this yet.\n                    member.mode = None  # type: ignore [assignment]\n                return member\n\n            tar.extractall(location, filter=pip_filter)\n\n    finally:","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/utils/unpacking.py#L220-L256","documentation":"Raised as InstallationError by untar_file's pip_filter (unpacking.py:238) when a tar archive member fails the data_filter extraction safety check. Python 3.12+'s tarfile.data_filter (PEP 706) blocks dangerous entries: absolute paths, path traversal (../), hardlinks/symlinks pointing outside the destination, device files, etc. pip wraps the filter to also apply executable permissions; any TarError from the filter is re-raised as InstallationError with the member and error detail.","triggerScenarios":"During installation of a sdist tarball, untar_file calls tar.extractall with pip_filter at line 254. The filter calls data_filter(member, location) at line 219; if the member is unsafe (traversal, absolute path, dangerous link), a TarError is raised and caught at line 234, then re-raised as InstallationError at 238. There is a special case (lines 220-233) that downgrades LinkOutsideDestinationError to tar_filter on specific buggy Python patch versions.","commonSituations":"A malicious or malformed sdist tarball containing entries that try to write outside the target directory. A tarball built on a system with absolute paths or symlinks that the filter considers unsafe. A corrupted or partially-downloaded archive.","solutions":["Verify the package source is trusted and re-download from the official index to rule out corruption.","Report the package to PyPI / the maintainer if it contains entries that trip the safety filter — it may be malicious or buggy.","Avoid installing from untrusted direct-URL tarballs; use wheels from vetted indices when available.","If you maintain the package, rebuild the sdist ensuring all members are relative paths without symlinks escaping the archive root."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import tarfile, os\n\ndef check_tar_for_unsafe_members(tar_path: str, dest: str) -> list[str]:\n    \"\"\"Return list of unsafe tar members using the data_filter.\"\"\"\n    dest = os.path.abspath(dest)\n    unsafe = []\n    with tarfile.open(tar_path) as tf:\n        for member in tf.getmembers():\n            try:\n                tarfile.data_filter(member, dest)\n            except (tarfile.TarError, ValueError) as e:\n                unsafe.append(f'{member.name}: {e}')\n    return unsafe","typeGuard":"import tarfile\n\ndef is_safe_tar_member(member: tarfile.TarInfo, dest: str) -> bool:\n    \"\"\"True if the tar member passes the PEP 706 data_filter.\"\"\"\n    try:\n        tarfile.data_filter(member, dest)\n        return True\n    except tarfile.TarError:\n        return False","tryCatchPattern":"from pip._internal.exceptions import InstallationError\n\ntry:\n    # untar / install sdist operation\n    pass\nexcept InstallationError as e:\n    if 'Invalid member in the tar file' in str(e):\n        # Unsafe tar entry detected: do NOT extract; report as security issue\n        pass","preventionTips":["Only install sdists from trusted sources — prefer wheels from vetted indices.","Pre-scan downloaded tarballs with tarfile.data_filter before extraction.","Keep Python updated to get the latest tarfile security fixes (PEP 706).","Treat tar-slip detection as a security incident and report the package upstream."],"tags":["security","tar-slip","path-traversal","unpacking","tarfile","pep-706"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}