VYPR
Unrated severityNVD Advisory· Published May 26, 2026

CVE-2026-42497

CVE-2026-42497

Description

Archive::Tar versions before 3.08 for Perl extract hardlinks to attacker controlled paths outside the extraction directory.

_make_special_file() passes the tar header's linkname to link() without validating it against absolute paths or .. segments, creating a hardlink that shares the victim file's inode.

A subsequent write through the extracted name modifies the victim file, and the post-extraction chmod, chown, and utime block in _extract_file() (guarded only against symlinks via -l) applies the tar header's mode, owner, and timestamps to the shared inode during extraction alone.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Archive::Tar before 3.08 for Perl lacks validation of hardlink linknames, allowing extraction of hardlinks to attacker-controlled paths outside the extraction directory.

Vulnerability

Archive::Tar versions before 3.08 for Perl contain a path traversal and arbitrary hardlink creation vulnerability in the _make_special_file() function [1]. When extracting a tar entry that is a hardlink, _make_special_file() passes the tar header's linkname directly to the link() system call without validating that the target path is not absolute or does not contain .. segments [1]. An attacker who can craft a tar file with a specially crafted linkname can cause a hardlink to be created pointing to any file on the filesystem that the extracting process has access to [1]. The affected code is in lib/Archive/Tar.pm [1]. Patched in version 3.08 [2].

Exploitation

An attacker needs to craft a tar archive with a hardlink entry whose linkname is either an absolute path (e.g., /etc/passwd) or a relative path containing .. traversals (e.g., ../../../etc/passwd) [1]. The attacker must deliver this tar archive to a victim who then extracts it using Archive::Tar without the fix [1]. No special network position or authentication is required beyond the ability to provide the tar file (e.g., via a download, email attachment, or upload) [1].

Impact

Upon successful extraction, a hardlink is created that shares the inode of the victim file [1]. Because the tar extraction process also applies chmod, chown, and utime to extracted files (including hardlinks) during the _extract_file() block, the attacker can modify the mode, owner, and timestamps of the targeted file [1]. Additionally, any subsequent write through the extracted name will modify the original file's content [1]. This can lead to unauthorized modification of sensitive system files, potentially enabling privilege escalation or denial of service [1].

Mitigation

Upgrade to Archive::Tar version 3.08 or later, which adds validation of hardlink linknames (and symlink linknames) in SECURE_EXTRACT_MODE to reject absolute paths and traversal attempts [1][2]. Version 3.08 was released on 2026-05-26 [2]. If upgrading is not possible, avoid extracting untrusted tar archives with Archive::Tar, or use an alternative extraction tool that validates link targets. There is no workaround within older versions of Archive::Tar itself [1]. This vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog as of publication.

AI Insight generated on May 26, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

1
17c873492a05

Validate symlink and hardlink linkname in SECURE MODE

https://github.com/jib/archive-tar-newStig PalmquistMay 21, 2026via nvd-ref
2 files changed · +32 0
  • lib/Archive/Tar.pm+30 0 modified
    @@ -955,6 +955,19 @@ sub _make_special_file {
         my $err;
     
         if( $entry->is_symlink ) {
    +        if( !$INSECURE_EXTRACT_MODE ) {
    +            my $linkname = $entry->linkname;
    +            if( File::Spec->file_name_is_absolute($linkname) ) {
    +                $self->_error( qq[Symlink '] . $entry->full_path .
    +                    qq[' has absolute target. Not extracting under SECURE EXTRACT MODE] );
    +                return;
    +            }
    +            if( grep { $_ eq '..' } File::Spec->splitdir($linkname) ) {
    +                $self->_error( qq[Symlink '] . $entry->full_path .
    +                    qq[' target attempts traversal. Not extracting under SECURE EXTRACT MODE] );
    +                return;
    +            }
    +        }
             my $fail;
             if( ON_UNIX ) {
                 symlink( $entry->linkname, $file ) or $fail++;
    @@ -968,6 +981,23 @@ sub _make_special_file {
                     $entry->linkname .q[' failed] if $fail;
     
         } elsif ( $entry->is_hardlink ) {
    +        if( !$INSECURE_EXTRACT_MODE ) {
    +            my $linkname = $entry->linkname;
    +            if( File::Spec->file_name_is_absolute($linkname) ) {
    +                $self->_error( qq[Hardlink '] . $entry->full_path .
    +                    qq[' has absolute target '$linkname'. Not extracting ] .
    +                    qq[under SECURE EXTRACT MODE: extraction itself chmods ] .
    +                    qq[the shared inode.] );
    +                return;
    +            }
    +            if( grep { $_ eq '..' } File::Spec->splitdir($linkname) ) {
    +                $self->_error( qq[Hardlink '] . $entry->full_path .
    +                    qq[' target '$linkname' attempts traversal. Not ] .
    +                    qq[extracting under SECURE EXTRACT MODE: extraction ] .
    +                    qq[itself chmods the shared inode.] );
    +                return;
    +            }
    +        }
             my $fail;
             if( ON_UNIX && $EXTRACT_HARDLINK ) {
                 link( $entry->linkname, $file ) or $fail++;
    
  • t/04_resolved_issues.t+2 0 modified
    @@ -220,6 +220,7 @@ if ($^O ne 'msys') # symlink tests fail on Windows/msys2
     		}
     
         { #use case 1 - in memory extraction
    +      local $Archive::Tar::INSECURE_EXTRACT_MODE=1;
     			my $t=Archive::Tar->new;
     			$t->read( $archname );
     			my $r = eval{ $t->extract };
    @@ -231,6 +232,7 @@ if ($^O ne 'msys') # symlink tests fail on Windows/msys2
     
     		{ #use case 2 - iter extraction
     		  #$DB::single = 2;
    +      local $Archive::Tar::INSECURE_EXTRACT_MODE=1;
     			my $next=Archive::Tar->iter( $archname, 1 );
     			my $failed = 0;
     			#use Data::Dumper;
    

Vulnerability mechanics

Root cause

"Missing validation of hardlink and symlink linkname in _make_special_file() allows absolute paths and .. traversal to reach the link() system call."

Attack vector

An attacker crafts a tar archive containing a hardlink entry whose linkname is an absolute path (e.g., `/etc/crontab`) or a relative traversal path (e.g., `../../etc/crontab`). When Archive::Tar extracts the archive in the default SECURE EXTRACT MODE (before the fix), `_make_special_file()` calls `link()` with that attacker-controlled linkname, creating a hardlink inside the extraction directory that shares the inode of the victim file. Because `_extract_file()` applies the tar header's mode, owner, and timestamps to the extracted file and only skips that block for symlinks (not hardlinks), the attacker can modify the permissions, ownership, and metadata of any file on the system to which they have write access to the parent directory [ref_id=1].

Affected code

The vulnerability resides in `lib/Archive/Tar.pm`, in the `_make_special_file()` subroutine. The `link()` call for hardlinks (line ~988) and the `symlink()` call for symlinks (line ~965) pass `$entry->linkname` directly from the tar header without any validation against absolute paths or `..` traversal segments. The `_extract_file()` block that applies `chmod`, `chown`, and `utime` to the extracted file guards only against symlinks (via `-l`) and does not protect against hardlinks that share an inode with a file outside the extraction directory [patch_id=2539784].

What the fix does

The patch adds validation in `_make_special_file()` for both symlinks and hardlinks when `$INSECURE_EXTRACT_MODE` is not set. It uses `File::Spec->file_name_is_absolute()` to reject absolute link targets and checks for `..` segments via `File::Spec->splitdir()`. If either check fails, the entry is skipped with an error message and extraction is aborted. This closes the vulnerability by preventing the `link()` or `symlink()` call from ever receiving an attacker-controlled path that points outside the extraction directory [patch_id=2539784].

Preconditions

  • configThe victim must extract a tar archive using Archive::Tar in the default SECURE EXTRACT MODE (i.e., $INSECURE_EXTRACT_MODE is not set to 1).
  • inputThe attacker must be able to craft a tar archive with a hardlink entry whose linkname is an absolute path or contains .. traversal.
  • authThe victim file targeted by the hardlink must be writable by the user running the extraction (or the extraction must run with sufficient privileges for chmod/chown to be applied).

Generated on May 26, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.