From fa6b0df20aa99da27bfd61341c1939bdeabb713f Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Wed, 29 May 2024 16:32:41 +0200 Subject: [PATCH] :seedling: Small refactor and test for remediations Signed-off-by: Arnout Engelen --- checks/raw/pinned_dependencies.go | 23 ++++++--- checks/raw/pinned_dependencies_test.go | 70 ++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/checks/raw/pinned_dependencies.go b/checks/raw/pinned_dependencies.go index 26436f09ca4a..b5fd2d0042c9 100644 --- a/checks/raw/pinned_dependencies.go +++ b/checks/raw/pinned_dependencies.go @@ -228,14 +228,18 @@ func collectDockerfilePinning(c *checker.CheckRequest, r *checker.PinningDepende return err } - for i := range r.Dependencies { - rr := &r.Dependencies[i] + applyDockerfilePinningRemediations(r.Dependencies) + return nil +} + +func applyDockerfilePinningRemediations(d []checker.Dependency) { + for i := range d { + rr := &d[i] if rr.Type == checker.DependencyUseTypeDockerfileContainerImage && !*rr.Pinned { remediate := remediation.CreateDockerfilePinningRemediation(rr, remediation.CraneDigester{}) rr.Remediation = remediate } } - return nil } var validateDockerfilesPinning fileparser.DoWhileTrueOnFileContent = func( @@ -483,14 +487,19 @@ func collectGitHubActionsWorkflowPinning(c *checker.CheckRequest, r *checker.Pin //nolint:errcheck remediationMetadata, _ := remediation.New(c) - for i := range r.Dependencies { - rr := &r.Dependencies[i] + applyWorkflowPinningRemediations(remediationMetadata, r.Dependencies) + return nil +} + +func applyWorkflowPinningRemediations(rm *remediation.RemediationMetadata, d []checker.Dependency) { + for i := range d { + rr := &d[i] if rr.Type == checker.DependencyUseTypeGHAction && !*rr.Pinned { - remediate := remediationMetadata.CreateWorkflowPinningRemediation(rr.Location.Path) + remediate := rm.CreateWorkflowPinningRemediation(rr.Location.Path) rr.Remediation = remediate } } - return nil + } // validateGitHubActionWorkflow checks if the workflow file contains unpinned actions. Returns true if the check diff --git a/checks/raw/pinned_dependencies_test.go b/checks/raw/pinned_dependencies_test.go index dedd64bb04ad..d3a7586ed062 100644 --- a/checks/raw/pinned_dependencies_test.go +++ b/checks/raw/pinned_dependencies_test.go @@ -28,6 +28,7 @@ import ( "github.com/ossf/scorecard/v5/checker" mockrepo "github.com/ossf/scorecard/v5/clients/mockclients" "github.com/ossf/scorecard/v5/finding" + "github.com/ossf/scorecard/v5/remediation" scut "github.com/ossf/scorecard/v5/utests" ) @@ -415,6 +416,75 @@ func TestDockerfilePinning(t *testing.T) { } } +func TestMixedPinning(t *testing.T) { + t.Parallel() + + workflowDependency := checker.Dependency{ + Name: stringAsPointer("actions/checkout"), + PinnedAt: stringAsPointer("daadedc81d5f9d3c06d2c92f49202a3cc2b919ba"), + Location: &checker.File{ + Path: ".github/workflows/workflow-not-pinned.yaml", + Snippet: "actions/checkout@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba", + Offset: 31, + EndOffset: 31, + FileSize: 0, + Type: 1, + }, + Pinned: boolAsPointer(false), + Type: "GitHubAction", + Remediation: nil, + } + dockerDependency := checker.Dependency{ + Name: stringAsPointer("python"), + PinnedAt: stringAsPointer("3.7"), + Location: &checker.File{ + Path: "./testdata/Dockerfile-not-pinned", + Snippet: "FROM python:3.7", + Offset: 17, + EndOffset: 17, + Type: 0, + }, + Pinned: boolAsPointer(false), + Type: "containerImage", + } + dependencies := []checker.Dependency{ + workflowDependency, + dockerDependency, + } + + //nolint:errcheck + remediationMetadata, _ := remediation.New(nil) + remediationMetadata.Branch = "mybranch" + remediationMetadata.Repo = "myrepo" + + applyWorkflowPinningRemediations(remediationMetadata, dependencies) + if dependencies[0].Remediation == nil { + t.Errorf("No remediation added to workflow dependency") + return + } + if !strings.Contains(dependencies[0].Remediation.Text, "update your workflow") { + t.Errorf("Unexpected workflow remediation text") + } + if dependencies[1].Remediation != nil { + t.Errorf("Unexpected docker remediation") + return + } + applyDockerfilePinningRemediations(dependencies) + if dependencies[0].Remediation == nil { + t.Errorf("Remediation disappeared from workflow dependency") + } + if !strings.Contains(dependencies[0].Remediation.Text, "update your workflow") { + t.Errorf("Unexpected workflow remediation text") + } + if dependencies[1].Remediation == nil { + t.Errorf("No remediation added to docker dependency") + return + } + if !strings.Contains(dependencies[1].Remediation.Text, "Docker") { + t.Errorf("Unexpected Docker remediation text") + } +} + func TestFileIsInVendorDir(t *testing.T) { t.Parallel() tests := []struct {