Skip to content

Prevent extraction from escaping destination_dir via pre-existing symlinks#9493

Open
thesmartshadow wants to merge 1 commit intoruby:masterfrom
thesmartshadow:fix/cwe59-symlink-extract
Open

Prevent extraction from escaping destination_dir via pre-existing symlinks#9493
thesmartshadow wants to merge 1 commit intoruby:masterfrom
thesmartshadow:fix/cwe59-symlink-extract

Conversation

@thesmartshadow
Copy link
Copy Markdown

What was the end-user or developer problem that led to this PR?

When extracting a gem, RubyGems correctly rejects obvious path traversal patterns such as absolute paths or .., but it can still follow a pre-existing symlink inside the destination directory.

In practice, if part of the extraction path already exists as a symlink pointing outside the extraction root, a file that appears to be written under destination_dir can end up being written outside of it instead. That breaks the expected safety boundary of extraction and makes extraction unsafe in reused or shared directories.

What is your fix for the problem, implemented in this PR?

This PR adds a link-aware safety check before writing extracted files.

After ensuring the parent directory exists, it resolves the real path of that parent directory and verifies that it still stays under the intended extraction root. If the resolved parent path escapes destination_dir, extraction now raises Gem::Package::PathError instead of continuing with the write.

This keeps extraction confined to the intended destination even when pre-existing symlinks are present in the path.

This PR also adds a regression test covering that case by planting a symlink in the destination path and asserting that:

  • extraction raises Gem::Package::PathError
  • no file is written outside the extraction root

Validation

I verified the change with:

  • the regression test added in this PR
  • the existing nearby symlink-related tests
  • a local reproducer that previously wrote outside the extraction root and now fails with Gem::Package::PathError

Checklist

  • Describe the problem / feature
  • Write tests for features and bug fixes
  • Write code to solve the problem
  • Make sure you follow the current code style and write meaningful commit messages without tags

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant