Skip to content

IPC::Run::run() might run executables that are explicitly added to PATH #162

Open
@szmate1618

Description

@szmate1618

The minimal reproducible example I found is the following (in Powershell):

$Env:PATH="C:\Windows\system32\mspaint.exe"
.\perl.exe -e "use IPC::Run qw(run); my @SomeUndefinedArray = undef; run \@SomeUndefinedArray;"

This will start mspaint.exe, but it could be any executable. The .exe extension can be omitted, as PATHEXT is also taken into account.
I believe this is a bug and a potential security issue, as I don't expect run to run anything else than what I pass as an argument.
Of course, normally PATH should only contain directories, not executables, but I found it to be fairly easy to accidentally copy-paste a full path to an executable into it. That's how I discovered this behavior.

The root cause of the issue seems to be that passing \@SomeUndefinedArray to run passes an empty string to _search_path which empty string then will be concatenated to every path found in PATH and executed if it points to an executable.
Unfortunately every executable path on PATH + an empty string is guaranteed to point to an executable path.

The issue seems to be only present on Windows. I believe the reason for this is the different behavior of File::Spec->catfile() between different OSs:
Windows:

> perl.exe -e "use File::Spec; print(File::Spec->catfile('a',''));"
a

WSL terminal:

$ perl -e "use File::Spec; print(File::Spec->catfile('a',''));"
a/

for whatever reason Mac seems to do this:

> perl-e "use File::Spec; print(File::Spec->catfile('a',''));"
a/%

Note the missing trailing separator on Windows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions