in reply to Browser::Open Windows metacharacters

Browser::Open tries to use the list form of system to spawn a browser. The problem is that start is a cmd command and not a real executable, so Perl has to fall back to using the shell to launch it - and it doesn't quote the command line correctly in process. This makes Browser::Open a shell injection on Windows.

A proper solution would be either to use Win32::ShellQuote or something similar to build a proper cmd.exe command line on Windows, use Perl version of ShellExecute from WinAPI (is there such a module?) or to fall back to launching browsers directly by their paths, which is not a good idea at all.

Replies are listed 'Best First'.
Re^2: Browser::Open Windows metacharacters
by Jenda (Abbot) on Dec 10, 2018 at 00:09 UTC
    use Win32::FileOp qw(ShellExecute); ShellExecute("http://www.google.com?foo=1&bar=2");

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

      Hello Jenda,

      ShellExecute does the job nicely, and Win32::FileOp looks to be a useful module.

      Unfortunately, when I tried to install it on my system (Windows 8.1, 64-bit), I got a gmake error similar to the one reported in Bug #71759. XLAT’s fork on GitHub (version “0.16.03”) fixed the problem for me. I note that although the status for Bug #71759 is “open,” it is also marked as “Fixed in: 0.16.02,” which would seem to be incorrect.

      Just a heads-up,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re^2: Browser::Open Windows metacharacters
by IB2017 (Pilgrim) on Dec 09, 2018 at 21:15 UTC

    Thank you for your help, and expecially for pointing to Win32::ShellQuote that I was not aware of. I found that having Browser::Open this shortcoming, the easiest solution for my case is the following script I found here. It just works, and for the moment I do not see any drawback:

    sub openurl { my $url = shift; my $platform = $^O; my $cmd; if ($platform eq 'darwin') { $cmd = "open \"$url\""; } # +OS X elsif ($platform eq 'MSWin32' or $platform eq 'msys') { $cmd = "star +t \"\" \"$url\""; } # Windows native or MSYS / Git Bash elsif ($platform eq 'cygwin') { $cmd = "cmd.exe /c start \"\" \"$ur +l \""; } # Cygwin; !! Note the required trailing space. else { $cmd = "xdg-open \"$url\""; } # assume a Freedesktop-complia +nt OS, which includes many Linux distros, PC-BSD, OpenSolaris, ... if (system($cmd) != 0) { die "Cannot locate or failed to open default browser; please open +'$url' manually."; } }
      Make sure you trust the source of the URLs. Otherwise it's still a shell injection: try passing a $url = q["$(touch ~/hello.txt)"] if you're on Linux or maybe $url = q["&calc&"] on Windows (not sure about the CMD syntax, but it's definitely possible to construct a string that would cause a command to be run when wrapped in double quotes).

        Thank you for pointing me to this threat. In this case my script generates the URLs, so it should be fine.