On Windows, a double quotation mark (U+0022) in a command argument causes the
argument to expand into multiple arguments:
#! /usr/bin/perl
# Test results w/ Strawberry Perl v5.26.1 and IPC::Run at git commit 211e794.
# Behaviors in question are older. Same result with ActivePerl v5.24.1.
use strict;
use warnings;
use IPC::Run ();
use Config;
# envision a real program where this argument comes from an untrusted source
my $arg;
$ENV{PATH} = '/usr/bin' if ${^TAINT};
my $perl = $Config{perlpath};
$perl .= $Config{_exe} unless $perl =~ /$Config{_exe}$/i;
# CreateProcess gets: C:\STRAWB~1\perl\bin\perl.exe "-V:u32size \""" -Mnosuch_example"
# got: Can't locate nosuch_example.pm in @INC (you may need to install the nosuch_example module) (@INC contains: C:/Strawberry/perl/site/lib C:/Strawberry/perl/vendor/lib C:/Strawberry/perl/lib .).
# wanted: -Mnosuch_example: not found;
$arg = 'u32size \" -Mnosuch_example';
IPC::Run::run [$perl, "-V:$arg"];
When the argument source is not trusted, this can create a security
vulnerability. I discussed the matter with perl5-security-report@perl.org,
but we decided to give up on fixing it in private. (Perl/perl5#14434 is a
similar vulnerability in core Perl, but the cause is different.)
While Unix has a native argv[] concept, the closest native Windows analog is
the GetCommandLine() string. Most applications use standard Microsoft startup
code to parse the command line into an argv[] according to rules in
https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args#parsing-c-command-line-arguments.
There is no Windows API for serializing an array of argument strings into a
command line string. IPC::Run's win32_spawn() attempts to quote arguments,
without following all those rules.
On Windows, a double quotation mark (U+0022) in a command argument causes the argument to expand into multiple arguments:
When the argument source is not trusted, this can create a security vulnerability. I discussed the matter with perl5-security-report@perl.org, but we decided to give up on fixing it in private. (Perl/perl5#14434 is a similar vulnerability in core Perl, but the cause is different.)
While Unix has a native argv[] concept, the closest native Windows analog is the GetCommandLine() string. Most applications use standard Microsoft startup code to parse the command line into an argv[] according to rules in https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args#parsing-c-command-line-arguments. There is no Windows API for serializing an array of argument strings into a command line string. IPC::Run's win32_spawn() attempts to quote arguments, without following all those rules.