On Windows, sbt uses Process("cmd", "/c", ...) to run VCS commands (git, hg, svn). The URI fragment (branch, tag, revision) is user-controlled via the build definition and passed to these commands without validation. Because cmd /c interprets &, |, and ; as command separators, a malicious fragment can execute arbitrary commands.
Technically, sbt 1.12.7 is patched, but it has a bug that makes source dependency non-functional, so update to sbt 1.12.8 or later instead.
uri.getFragment() to run() without sanitizationrun() uses Process("cmd", "/c", ...) on Windows, so cmd interprets && as command separator# build.properties
# sbt.version=1.12.5 # Tested on those two versions of sbt
sbt.version=2.0.0-RC9
// build.sbt
ThisBuild / scalaVersion := "2.12.19"
lazy val root = project
.in(file("."))
.dependsOn(vulnerable)
lazy val vulnerable = RootProject(
uri("https://github.com/sbt/io.git#develop%26%26calc.exe")
)
Windows users are impacted. An attacker can execute arbitrary Windows commands if they control the dependency URI.
{
"cwe_ids": [
"CWE-78"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-24T16:04:12Z",
"nvd_published_at": "2026-03-24T20:16:27Z",
"severity": "MODERATE"
}