From 951b02dd95559b1a26f2456bfb97cf740ea40934 Mon Sep 17 00:00:00 2001 From: Tristan Cacqueray Date: Sat, 3 Aug 2024 09:31:14 -0400 Subject: [PATCH] Prevent command-line injection for batch files with trailing char This change ensure the regime implemented for HSEC-2024-0003 is applied to batch file names ending with trailing chars that are ignored by Windows. --- System/Process/Windows.hsc | 19 ++++++++++++++++++- changelog.md | 6 ++++++ process.cabal | 2 +- test/process-tests.cabal | 4 ++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/System/Process/Windows.hsc b/System/Process/Windows.hsc index ed0113de..6d6a9f6f 100644 --- a/System/Process/Windows.hsc +++ b/System/Process/Windows.hsc @@ -28,6 +28,7 @@ import Control.Exception import Control.Monad import Data.Bits import Data.Char (toLower) +import Data.List (dropWhileEnd) import Foreign.C import Foreign.Marshal import Foreign.Ptr @@ -429,11 +430,27 @@ commandToProcess (ShellCommand string) = do -- I don't have the energy to find+fix them right now (ToDo). --SDM -- (later) Now I don't know what the above comment means. sigh. commandToProcess (RawCommand cmd args) - | map toLower (takeExtension cmd) `elem` [".bat", ".cmd"] + | map toLower (takeWinExtension cmd) `elem` [".bat", ".cmd"] = return (cmd, translateInternal cmd ++ concatMap ((' ':) . translateCmdExeArg) args) | otherwise = return (cmd, translateInternal cmd ++ concatMap ((' ':) . translateInternal) args) +-- TODO: filepath should also be updated with 'takeWinExtension'. Perhaps +-- some day we can remove this logic from `process` but there is no hurry. + +-- | Get the extension of a Windows file, removing any trailing spaces or dots +-- since they are ignored. +-- +-- See: +-- +-- >>> takeWinExtension "test.bat." +-- ".bat" +-- +-- >>> takeWinExtension "test.bat ." +-- ".bat" +takeWinExtension :: FilePath -> String +takeWinExtension = takeExtension . dropWhileEnd (`elem` [' ', '.']) + -- Find CMD.EXE (or COMMAND.COM on Win98). We use the same algorithm as -- system() in the VC++ CRT (Vc7/crt/src/system.c in a VC++ installation). findCommandInterpreter :: IO FilePath diff --git a/changelog.md b/changelog.md index 7795d9df..6ee59e8e 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog for [`process` package](http://hackage.haskell.org/package/process) +## 1.6.23.0 *September 2024* + +* Fix command-line escaping logic on Windows when the command file ends with + a space or a dot. This is a follow-up for + [HSEC-2024-0003](https://github.com/haskell/security-advisories/tree/main/advisories/hackage/process/HSEC-2024-0003.md). + ## 1.6.22.0 *August 2024* * Allow NUL to appear in arguments under POSIX. See diff --git a/process.cabal b/process.cabal index 65c6f5a3..ced26259 100644 --- a/process.cabal +++ b/process.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: process -version: 1.6.22.0 +version: 1.6.23.0 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause license-file: LICENSE diff --git a/test/process-tests.cabal b/test/process-tests.cabal index 70f5b036..a8adf92d 100644 --- a/test/process-tests.cabal +++ b/test/process-tests.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: process-tests -version: 1.6.21.0 +version: 1.6.23.0 license: BSD-3-Clause license-file: LICENSE maintainer: libraries@haskell.org @@ -18,7 +18,7 @@ source-repository head common process-dep build-depends: - process == 1.6.22.0 + process == 1.6.23.0 custom-setup setup-depends: