diff --git a/checks/pinned_dependencies_test.go b/checks/pinned_dependencies_test.go index 0eeb9a60327..2d9f120d095 100644 --- a/checks/pinned_dependencies_test.go +++ b/checks/pinned_dependencies_test.go @@ -245,7 +245,7 @@ func TestGithubWorkflowPkgManagerPinning(t *testing.T) { expected: scut.TestReturn{ Error: nil, Score: checker.MinResultScore, - NumberOfWarn: 26, + NumberOfWarn: 28, NumberOfInfo: 0, NumberOfDebug: 0, }, @@ -692,6 +692,16 @@ func TestShellscriptInsecureDownloadsLineNumber(t *testing.T) { startLine: 28, endLine: 28, }, + { + snippet: "choco install 'some-package'", + startLine: 30, + endLine: 30, + }, + { + snippet: "choco install 'some-other-package'", + startLine: 31, + endLine: 31, + }, }, }, } @@ -936,7 +946,7 @@ func TestDockerfileScriptDownload(t *testing.T) { expected: scut.TestReturn{ Error: nil, Score: checker.MinResultScore, - NumberOfWarn: 37, + NumberOfWarn: 39, NumberOfInfo: 0, NumberOfDebug: 0, }, @@ -1100,7 +1110,7 @@ func TestShellScriptDownload(t *testing.T) { expected: scut.TestReturn{ Error: nil, Score: checker.MinResultScore, - NumberOfWarn: 34, + NumberOfWarn: 36, NumberOfInfo: 0, NumberOfDebug: 0, }, diff --git a/checks/shell_download_validate.go b/checks/shell_download_validate.go index 85fb589825e..3e9c28c5107 100644 --- a/checks/shell_download_validate.go +++ b/checks/shell_download_validate.go @@ -575,6 +575,39 @@ func isPipUnpinnedDownload(cmd []string) bool { return false } +func isChocoUnpinnedDownload(cmd []string) bool { + // Install command is in the form 'choco install ...' + if len(cmd) < 2 { + return false + } + + if !isBinaryName("choco", cmd[0]) && !isBinaryName("choco.exe", cmd[0]) { + return false + } + + if !strings.EqualFold(cmd[1], "install") { + return false + } + + // If this is an install command, then some variant of requirechecksum must be present. + for i := 1; i < len(cmd); i++ { + parts := strings.Split(cmd[i], "=") + if len(parts) == 0 { + continue + } + + str := parts[0] + + if strings.EqualFold(str, "--requirechecksum") || + strings.EqualFold(str, "--requirechecksums") || + strings.EqualFold(str, "--require-checksums") { + return false + } + } + + return true +} + func isUnpinnedPakageManagerDownload(startLine, endLine uint, node syntax.Node, cmd, pathfn string, dl checker.DetailLogger, ) bool { @@ -629,6 +662,18 @@ func isUnpinnedPakageManagerDownload(startLine, endLine uint, node syntax.Node, return true } + // Choco install. + if isChocoUnpinnedDownload(c) { + dl.Warn(&checker.LogMessage{ + Path: pathfn, + Type: checker.FileTypeSource, + Offset: startLine, + EndOffset: endLine, + Snippet: cmd, + Text: "choco installation not pinned by hash", + }) + return true + } // TODO(laurent): add other package managers. return false diff --git a/checks/testdata/.github/workflows/github-workflow-pkg-managers.yaml b/checks/testdata/.github/workflows/github-workflow-pkg-managers.yaml index 7a0fc4919d2..42136653b0f 100644 --- a/checks/testdata/.github/workflows/github-workflow-pkg-managers.yaml +++ b/checks/testdata/.github/workflows/github-workflow-pkg-managers.yaml @@ -98,3 +98,13 @@ jobs: run: python -m pip install 'some-pkg>1.2.3' - name: run: pip3 install -r bla-requirements.txt --require-hashes && pip3 install --require-hashes -r bla-requirements.txt + - name: + run: choco install 'some-package' + - name: + run: choco install 'some-other-package' + - name: + run: choco install --requirechecksum 'some-package' + - name: + run: choco install --requirechecksums 'some-package' + - name: + run: choco install --require-checksums 'some-package' \ No newline at end of file diff --git a/checks/testdata/Dockerfile-pkg-managers b/checks/testdata/Dockerfile-pkg-managers index 4ba72d17d61..d3ac28070f5 100644 --- a/checks/testdata/Dockerfile-pkg-managers +++ b/checks/testdata/Dockerfile-pkg-managers @@ -81,4 +81,10 @@ RUN npm install -g RUN npm i RUN npm ci RUN npm install-test -RUN npm install-ci-test \ No newline at end of file +RUN npm install-ci-test + +RUN choco install 'some-package' +RUN choco install 'some-other-package' +RUN choco install --requirechecksum 'some-package' +RUN choco install --requirechecksums 'some-package' +RUN choco install --require-checksums 'some-package' \ No newline at end of file diff --git a/checks/testdata/script-pkg-managers b/checks/testdata/script-pkg-managers index eb177887a02..29cb5cdc5ae 100644 --- a/checks/testdata/script-pkg-managers +++ b/checks/testdata/script-pkg-managers @@ -83,4 +83,10 @@ npm install -g npm i npm ci npm install-test -npm install-ci-test \ No newline at end of file +npm install-ci-test + +choco install 'some-package' +choco install 'some-other-package' +choco install --requirechecksum 'some-package' +choco install --requirechecksums 'some-package' +choco install --require-checksums 'some-package' \ No newline at end of file diff --git a/checks/testdata/shell-download-lines.sh b/checks/testdata/shell-download-lines.sh index 15215cf578b..8b5ab645fa9 100644 --- a/checks/testdata/shell-download-lines.sh +++ b/checks/testdata/shell-download-lines.sh @@ -25,4 +25,10 @@ echo hi; echo bla; bash <(wget -qO- http://website.com/my-script.sh) bla && \ pip install -r requirements.txt -bla && curl bla | bash \ No newline at end of file +bla && curl bla | bash + +choco install 'some-package' +choco install 'some-other-package' +choco install --requirechecksum 'some-package' +choco install --requirechecksums 'some-package' +choco install --require-checksums 'some-package' \ No newline at end of file