Skip to content

Commit 8b951f4

Browse files
authored
Call purescript with the shell enabled on Windows, as a workaround for CVE-2024-27980 (#1308)
1 parent bd87d82 commit 8b951f4

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

src/Spago/Cmd.purs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Node.Library.Execa as Execa
1313
import Node.Platform as Platform
1414
import Node.Process as Process
1515
import Partial.Unsafe (unsafeCrashWith, unsafePartial)
16+
import Unsafe.Coerce (unsafeCoerce)
1617

1718
data StdinConfig
1819
= StdinPipeParent
@@ -77,6 +78,7 @@ type ExecOptions =
7778
, pipeStdout :: Boolean
7879
, pipeStderr :: Boolean
7980
, cwd :: Maybe FilePath
81+
, shell :: Boolean
8082
}
8183

8284
defaultExecOptions :: ExecOptions
@@ -85,6 +87,7 @@ defaultExecOptions =
8587
, pipeStdout: true
8688
, pipeStderr: true
8789
, cwd: Nothing
90+
, shell: false
8891
}
8992

9093
spawn :: forall m. MonadAff m => String -> Array String -> ExecOptions -> m Execa.ExecaProcess
@@ -94,7 +97,18 @@ spawn cmd args opts = liftAff do
9497
StdinPipeParent -> Just inherit
9598
StdinWrite _ -> Just pipe
9699
StdinNewPipe -> Just pipe
97-
subprocess <- Execa.execa cmd args (_ { cwd = opts.cwd, stdin = stdinOpt, stdout = Just pipe, stderr = Just pipe })
100+
subprocess <- Execa.execa cmd args
101+
( _
102+
{ cwd = opts.cwd
103+
, stdin = stdinOpt
104+
, stdout = Just pipe
105+
, stderr = Just pipe
106+
, shell = case opts.shell of
107+
-- TODO: execa doesn't support the boolean option yet
108+
true -> Just (unsafeCoerce true)
109+
false -> Nothing
110+
}
111+
)
98112

99113
case opts.pipeStdin of
100114
StdinWrite s | Just { writeUtf8End } <- subprocess.stdin -> writeUtf8End s
@@ -189,22 +203,22 @@ getExecutable command =
189203
Just Platform.Win32 -> do
190204
-- On Windows, we often need to call the `.cmd` version
191205
let cmd1 = mkCmd command (Just "cmd")
192-
askVersion cmd1 >>= case _ of
206+
askVersion cmd1 true >>= case _ of
193207
Right r -> pure { cmd: cmd1, output: r.stdout }
194208
Left r -> do
195209
let cmd2 = mkCmd command Nothing
196210
logDebug [ "Failed to find purs.cmd. Trying with just purs...", show r.message ]
197-
askVersion cmd2 >>= case _ of
211+
askVersion cmd2 false >>= case _ of
198212
Right r' -> pure { cmd: cmd2, output: r'.stdout }
199213
Left r' -> complain r'
200214
_ -> do
201215
-- On other platforms, we just call `purs`
202216
let cmd1 = mkCmd command Nothing
203-
askVersion cmd1 >>= case _ of
217+
askVersion cmd1 false >>= case _ of
204218
Right r -> pure { cmd: cmd1, output: r.stdout }
205219
Left r -> complain r
206220
where
207-
askVersion cmd = exec cmd [ "--version" ] defaultExecOptions { pipeStdout = false, pipeStderr = false }
221+
askVersion cmd shell = exec cmd [ "--version" ] defaultExecOptions { pipeStdout = false, pipeStderr = false, shell = shell }
208222

209223
mkCmd cmd maybeExtension = cmd <> maybe "" (append ".") maybeExtension
210224

0 commit comments

Comments
 (0)