Skip to content

Check the resolved parent directory before extracting old format gems - #9755

Merged
hsbt merged 1 commit into
masterfrom
claude/old-package-realpath-hardening
Aug 4, 2026
Merged

Check the resolved parent directory before extracting old format gems#9755
hsbt merged 1 commit into
masterfrom
claude/old-package-realpath-hardening

Conversation

@hsbt

@hsbt hsbt commented Aug 4, 2026

Copy link
Copy Markdown
Member

Gem::Package::Old#extract_files validated entry paths only by expanding them against the destination directory, so a symlinked subdirectory that already exists under the extraction root redirected writes outside of it. Gem::Package#extract_tar_gz already re-resolves the parent directory with File.realpath, so this makes the legacy reader consistent with the modern one rather than fixing a vulnerability. Planting that symlink already requires write access to the extraction directory.

The shared check now lives in verify_extraction_dir and both readers call it. In the old format reader the FileUtils.rm_rf of the destination runs after the check, so a rejected entry cannot delete a file outside the root on its way out.

Gem::Package::Old#extract_files only validated entry paths by string
expansion, so a preexisting symlink in the extraction directory redirected
writes outside of it. Gem::Package#extract_tar_gz already re-resolves the
parent directory with File.realpath, so extract the shared check into
verify_extraction_dir and call it from both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@hsbt
hsbt merged commit d834fa4 into master Aug 4, 2026
107 checks passed
@hsbt
hsbt deleted the claude/old-package-realpath-hardening branch August 4, 2026 07:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant