Skip to content

phar: reject extractTo() when destination parent escapes via symlink#21808

Open
iliaal wants to merge 1 commit intophp:PHP-8.4from
iliaal:fix/phar-extractto-symlink-traversal
Open

phar: reject extractTo() when destination parent escapes via symlink#21808
iliaal wants to merge 1 commit intophp:PHP-8.4from
iliaal:fix/phar-extractto-symlink-traversal

Conversation

@iliaal
Copy link
Copy Markdown
Contributor

@iliaal iliaal commented Apr 18, 2026

Fixes destination-side symlink traversal in Phar::extractTo().

extractTo() builds the target path as dest + "/" + entry_path. CWD_EXPAND validates the entry path against .. traversal but doesn't resolve symlinks. A pre-existing symlink in the destination (e.g., /dest/subdir -> /etc) causes the extracted file to land outside the intended root.

After creating the parent directory, resolve it with VCWD_REALPATH and verify it stays under dest. Return FAILURE if it escapes so the caller throws a PharException.

The test skips on Windows only when SeCreateSymbolicLinkPrivilege is absent. Without it, symlink() returns false without error, so no symlink exists in the destination, extractTo() succeeds, and the test outputs EXTRACTED (unexpected) instead of the PharException that --EXPECTF-- requires.

Phar::extractTo() builds the target path as dest + "/" + entry_path.
CWD_EXPAND validates entry_path against ".." traversal but doesn't
resolve symlinks. A pre-existing symlink in the destination
(e.g., /dest/subdir -> /etc) writes the extracted file outside the
intended root.

After creating the parent directory, resolve it with VCWD_REALPATH
and verify it stays under dest. Return FAILURE if it escapes so the
caller throws a PharException.
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