diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c2429d844014..d4d22a3836bb 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -52,7 +52,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@9b0655f430fba8c7001d4e38f8d4306db5c6e0ab # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b7194e84cc4d..1a94ef004bae 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -40,7 +40,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -82,7 +82,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -124,7 +124,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -166,7 +166,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -208,7 +208,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -250,7 +250,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -292,7 +292,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/goreleaser.yaml b/.github/workflows/goreleaser.yaml index 175eef23f4db..9e841373052f 100644 --- a/.github/workflows/goreleaser.yaml +++ b/.github/workflows/goreleaser.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -50,7 +50,7 @@ jobs: - name: Import GPG key id: import_gpg - uses: crazy-max/ghaction-import-gpg@4d58d49bfefed583addec96996588e8bc4b306b8 # v3.1.0 + uses: crazy-max/ghaction-import-gpg@e00cb83a68c1158b29afc5217dd0582cada6d172 # v3.1.0 with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 11c1667c7d64..5eb44e7ca178 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -38,7 +38,7 @@ jobs: needs: [approve] steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 94bb7b241ece..00022e672c3d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,7 +37,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -75,7 +75,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -121,7 +121,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -165,7 +165,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -210,7 +210,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -255,7 +255,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -300,7 +300,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -345,7 +345,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -390,7 +390,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -435,7 +435,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -480,7 +480,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -525,7 +525,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -570,7 +570,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -615,7 +615,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -660,7 +660,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -704,7 +704,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -743,7 +743,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -784,7 +784,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Install Protoc @@ -827,7 +827,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -867,7 +867,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/ok-to-test.yml b/.github/workflows/ok-to-test.yml index ae24dc78e8a0..b1a39eb8e20e 100644 --- a/.github/workflows/ok-to-test.yml +++ b/.github/workflows/ok-to-test.yml @@ -27,7 +27,7 @@ jobs: if: ${{ github.event.issue.pull_request }} steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/publishimage.yml b/.github/workflows/publishimage.yml index a62f7aa3ff74..02aae5848ca6 100644 --- a/.github/workflows/publishimage.yml +++ b/.github/workflows/publishimage.yml @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/scorecard-analysis.yml b/.github/workflows/scorecard-analysis.yml index 2e6fe1d3a896..69dc9d16ed6c 100644 --- a/.github/workflows/scorecard-analysis.yml +++ b/.github/workflows/scorecard-analysis.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 93ca9abf429e..ac73a975bb1f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 864e7c4ef828..ecfd61a3f1e8 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bdb12b622a910dfdc99a31fdfe6f45a16bc287a4 # v1 + uses: step-security/harden-runner@34cbc43f0b10c9dda284e663cf43c2ebaf83e956 # v1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/checker/check_result.go b/checker/check_result.go index 495f60f68a35..30e9fb13185e 100644 --- a/checker/check_result.go +++ b/checker/check_result.go @@ -79,7 +79,6 @@ const ( // nolint:govet type CheckResult struct { // TODO(#1393): Remove old structure after deprecation. - Error error `json:"-"` Name string Details []string Confidence int @@ -88,7 +87,7 @@ type CheckResult struct { // UPGRADEv2: New structure. Omitting unchanged Name field // for simplicity. Version int `json:"-"` // Default value of 0 indicates old structure. - Error2 error `json:"-"` // Runtime error indicate a filure to run the check. + Error error `json:"-"` // Runtime error indicate a filure to run the check. Details2 []CheckDetail `json:"-"` // Details of tests and sub-checks Score int `json:"-"` // {[-1,0...10], -1 = Inconclusive} Reason string `json:"-"` // A sentence describing the check result (score, etc) @@ -161,12 +160,11 @@ func CreateResultWithScore(name, reason string, score int) CheckResult { return CheckResult{ Name: name, // Old structure. - Error: nil, Confidence: MaxResultScore, Pass: pass, // New structure. Version: 2, - Error2: nil, + Error: nil, Score: score, Reason: reason, } @@ -186,12 +184,11 @@ func CreateProportionalScoreResult(name, reason string, b, t int) CheckResult { return CheckResult{ Name: name, // Old structure. - Error: nil, Confidence: MaxResultConfidence, Pass: pass, // New structure. Version: 2, - Error2: nil, + Error: nil, Score: score, Reason: NormalizeReason(reason, score), } @@ -232,12 +229,11 @@ func CreateRuntimeErrorResult(name string, e error) CheckResult { return CheckResult{ Name: name, // Old structure. - Error: e, Confidence: 0, Pass: false, // New structure. Version: 2, - Error2: e, + Error: e, Score: InconclusiveResultScore, Reason: e.Error(), // Note: message already accessible by caller thru `Error`. } diff --git a/checker/check_runner.go b/checker/check_runner.go index df80e7150800..e85979aba5ad 100644 --- a/checker/check_runner.go +++ b/checker/check_runner.go @@ -77,7 +77,7 @@ func logStats(ctx context.Context, startTime time.Time, result *CheckResult) err opencensusstats.Record(ctx, stats.CheckRuntimeInSec.M(runTimeInSecs)) if result.Error != nil { - ctx, err := tag.New(ctx, tag.Upsert(stats.ErrorName, sce.GetName(result.Error2))) + ctx, err := tag.New(ctx, tag.Upsert(stats.ErrorName, sce.GetName(result.Error))) if err != nil { return sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("tag.New: %v", err)) } @@ -109,9 +109,9 @@ func (r *Runner) Run(ctx context.Context, c Check) CheckResult { checkRequest.Ctx = ctx checkRequest.Dlogger = l res = c.Fn(&checkRequest) - if res.Error2 != nil && errors.Is(res.Error2, sce.ErrRepoUnreachable) { + if res.Error != nil && errors.Is(res.Error, sce.ErrRepoUnreachable) { checkRequest.Dlogger.Warn(&LogMessage{ - Text: fmt.Sprintf("%v", res.Error2), + Text: fmt.Sprintf("%v", res.Error), }) continue } diff --git a/checker/raw_result.go b/checker/raw_result.go index 2c3cbf2215cd..ee16274cd63c 100644 --- a/checker/raw_result.go +++ b/checker/raw_result.go @@ -20,6 +20,7 @@ import "time" // is applied. //nolint type RawResults struct { + CIIBestPracticesResults CIIBestPracticesData DangerousWorkflowResults DangerousWorkflowData VulnerabilitiesResults VulnerabilitiesData BinaryArtifactResults BinaryArtifactData @@ -258,6 +259,30 @@ type ReleaseAsset struct { URL string } +// CIIBadge corresponds to CII-Best-Practices badges. +// https://bestpractices.coreinfrastructure.org/en +type CIIBadge string + +const ( + // CIIBadgeUnknown or non-parsable CII Best Practices badge. + CIIBadgeUnknown CIIBadge = "unknown" + // CIIBadgeNotFound represents when CII Best Practices returns an empty response for a project. + CIIBadgeNotFound CIIBadge = "not_found" + // CIIBadgeInProgress state of CII Best Practices badge. + CIIBadgeInProgress CIIBadge = "in_progress" + // CIIBadgePassing for CII Best Practices badge. + CIIBadgePassing CIIBadge = "passing" + // CIIBadgeSilver for CII Best Practices badge. + CIIBadgeSilver CIIBadge = "silver" + // CIIBadgeGold for CII Best Practices badge. + CIIBadgeGold CIIBadge = "gold" +) + +// CIIBestPracticesData contains data foor CIIBestPractices check. +type CIIBestPracticesData struct { + Badge CIIBadge +} + // DangerousWorkflowData contains raw results // for dangerous workflow check. type DangerousWorkflowData struct { diff --git a/checks/cii_best_practices.go b/checks/cii_best_practices.go index ecc8d5be4487..b6c13ea1c256 100644 --- a/checks/cii_best_practices.go +++ b/checks/cii_best_practices.go @@ -15,20 +15,15 @@ package checks import ( - "fmt" - "github.com/ossf/scorecard/v4/checker" - "github.com/ossf/scorecard/v4/clients" + "github.com/ossf/scorecard/v4/checks/evaluation" + "github.com/ossf/scorecard/v4/checks/raw" sce "github.com/ossf/scorecard/v4/errors" ) -const ( - // CheckCIIBestPractices is the registered name for CIIBestPractices. - CheckCIIBestPractices = "CII-Best-Practices" - silverScore = 7 - passingScore = 5 - inProgressScore = 2 -) +// CheckCIIBestPractices is the registered name for CIIBestPractices. +const CheckCIIBestPractices = "CII-Best-Practices" + //nolint:gochecknoinits func init() { @@ -38,31 +33,19 @@ func init() { } } -// CIIBestPractices runs CII-Best-Practices check. +// CIIBestPractices will check if the maintainers have a best practice badge. func CIIBestPractices(c *checker.CheckRequest) checker.CheckResult { - if c.CIIClient == nil { - return checker.CreateInconclusiveResult(CheckCIIBestPractices, "CII client is nil") + rawData, err := raw.CIIBestPractices(c) + if err != nil { + e := sce.WithMessage(sce.ErrScorecardInternal, err.Error()) + return checker.CreateRuntimeErrorResult(CheckCIIBestPractices, e) } - // TODO: not supported for local clients. - badgeLevel, err := c.CIIClient.GetBadgeLevel(c.Ctx, c.Repo.URI()) - if err == nil { - switch badgeLevel { - case clients.NotFound: - return checker.CreateMinScoreResult(CheckCIIBestPractices, "no badge detected") - case clients.InProgress: - return checker.CreateResultWithScore(CheckCIIBestPractices, "badge detected: in_progress", inProgressScore) - case clients.Passing: - return checker.CreateResultWithScore(CheckCIIBestPractices, "badge detected: passing", passingScore) - case clients.Silver: - return checker.CreateResultWithScore(CheckCIIBestPractices, "badge detected: silver", silverScore) - case clients.Gold: - return checker.CreateMaxScoreResult(CheckCIIBestPractices, "badge detected: gold") - case clients.Unknown: - e := sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("unsupported badge: %v", badgeLevel)) - return checker.CreateRuntimeErrorResult(CheckCIIBestPractices, e) - } + // Return raw results. + if c.RawResults != nil { + c.RawResults.CIIBestPracticesResults = rawData } - e := sce.WithMessage(sce.ErrScorecardInternal, err.Error()) - return checker.CreateRuntimeErrorResult(CheckCIIBestPractices, e) + + // Return the score evaluation. + return evaluation.CIIBestPractices(CheckCIIBestPractices, c.Dlogger, &rawData) } diff --git a/checks/cii_best_practices_test.go b/checks/cii_best_practices_test.go index faf08d34b28e..81fe156a4623 100644 --- a/checks/cii_best_practices_test.go +++ b/checks/cii_best_practices_test.go @@ -66,21 +66,21 @@ func TestCIIBestPractices(t *testing.T) { name: "InProgressBadge", badgeLevel: clients.InProgress, expected: scut.TestReturn{ - Score: inProgressScore, + Score: 2, }, }, { name: "PassingBadge", badgeLevel: clients.Passing, expected: scut.TestReturn{ - Score: passingScore, + Score: 5, }, }, { name: "SilverBadge", badgeLevel: clients.Silver, expected: scut.TestReturn{ - Score: silverScore, + Score: 7, }, }, { diff --git a/checks/code_review_test.go b/checks/code_review_test.go index e3da2ff5e021..c616520e7c60 100644 --- a/checks/code_review_test.go +++ b/checks/code_review_test.go @@ -207,7 +207,7 @@ func TestCodereview(t *testing.T) { res := CodeReview(&req) if tt.err != nil { - if res.Error2 == nil { + if res.Error == nil { t.Errorf("Expected error %v, got nil", tt.err) } // return as we don't need to check the rest of the fields. diff --git a/checks/contributors_test.go b/checks/contributors_test.go index 5b663aa4768e..6df676bf538a 100644 --- a/checks/contributors_test.go +++ b/checks/contributors_test.go @@ -175,7 +175,7 @@ func TestContributors(t *testing.T) { res := Contributors(&req) if tt.err != nil { - if res.Error2 == nil { + if res.Error == nil { t.Errorf("Expected error %v, got nil", tt.err) } // return as we don't need to check the rest of the fields. diff --git a/checks/evaluation/binary_artifacts_test.go b/checks/evaluation/binary_artifacts_test.go index 049cbae91746..3f63ce166069 100644 --- a/checks/evaluation/binary_artifacts_test.go +++ b/checks/evaluation/binary_artifacts_test.go @@ -277,8 +277,8 @@ func TestBinaryArtifacts(t *testing.T) { t.Parallel() got := BinaryArtifacts(tt.args.name, tt.args.dl, tt.args.r) if tt.wantErr { - if got.Error2 == nil { - t.Errorf("BinaryArtifacts() error = %v, wantErr %v", got.Error2, tt.wantErr) + if got.Error == nil { + t.Errorf("BinaryArtifacts() error = %v, wantErr %v", got.Error, tt.wantErr) } } else { if got.Score != tt.want.Score { diff --git a/checks/evaluation/cii_best_practices.go b/checks/evaluation/cii_best_practices.go new file mode 100644 index 000000000000..ee711c1ac613 --- /dev/null +++ b/checks/evaluation/cii_best_practices.go @@ -0,0 +1,61 @@ +// Copyright Security Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package evaluation + +import ( + "fmt" + + "github.com/ossf/scorecard/v4/checker" + sce "github.com/ossf/scorecard/v4/errors" +) + +// Note: exported for unit tests. +const ( + silverScore = 7 + // Note: if this value is changed, please update the action's threshold score + // https://github.com/ossf/scorecard-action/blob/main/policies/template.yml#L61. + passingScore = 5 + inProgressScore = 2 +) + +// CIIBestPractices applies the score policy for the CIIBestPractices check. +func CIIBestPractices(name string, dl checker.DetailLogger, r *checker.CIIBestPracticesData) checker.CheckResult { + if r == nil { + e := sce.WithMessage(sce.ErrScorecardInternal, "empty raw data") + return checker.CreateRuntimeErrorResult(name, e) + } + + var results checker.CheckResult + switch r.Badge { + case checker.CIIBadgeNotFound: + results = checker.CreateMinScoreResult(name, "no badge detected") + case checker.CIIBadgeInProgress: + msg := fmt.Sprintf("badge detected: %v", r.Badge) + results = checker.CreateResultWithScore(name, msg, inProgressScore) + case checker.CIIBadgePassing: + msg := fmt.Sprintf("badge detected: %v", r.Badge) + results = checker.CreateResultWithScore(name, msg, passingScore) + case checker.CIIBadgeSilver: + msg := fmt.Sprintf("badge detected: %v", r.Badge) + results = checker.CreateResultWithScore(name, msg, silverScore) + case checker.CIIBadgeGold: + msg := fmt.Sprintf("badge detected: %v", r.Badge) + results = checker.CreateMaxScoreResult(name, msg) + case checker.CIIBadgeUnknown: + e := sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("unsupported badge: %v", r.Badge)) + results = checker.CreateRuntimeErrorResult(name, e) + } + return results +} diff --git a/checks/evaluation/dependency_update_tool_test.go b/checks/evaluation/dependency_update_tool_test.go index e39d337bd714..6fe381855b14 100644 --- a/checks/evaluation/dependency_update_tool_test.go +++ b/checks/evaluation/dependency_update_tool_test.go @@ -70,8 +70,8 @@ func TestDependencyUpdateTool(t *testing.T) { }, }, want: checker.CheckResult{ - Score: 0, - Error2: nil, + Score: 0, + Error: nil, }, err: false, expected: scut.TestReturn{ @@ -104,8 +104,8 @@ func TestDependencyUpdateTool(t *testing.T) { }, }, want: checker.CheckResult{ - Score: 10, - Error2: nil, + Score: 10, + Error: nil, }, expected: scut.TestReturn{ Error: nil, @@ -131,8 +131,8 @@ func TestDependencyUpdateTool(t *testing.T) { }, }, want: checker.CheckResult{ - Score: -1, - Error2: nil, + Score: -1, + Error: nil, }, expected: scut.TestReturn{ Error: sce.ErrScorecardInternal, @@ -147,8 +147,8 @@ func TestDependencyUpdateTool(t *testing.T) { dl: &scut.TestDetailLogger{}, }, want: checker.CheckResult{ - Score: -1, - Error2: nil, + Score: -1, + Error: nil, }, expected: scut.TestReturn{ Error: sce.ErrScorecardInternal, @@ -167,8 +167,8 @@ func TestDependencyUpdateTool(t *testing.T) { if tt.want.Score != got.Score { t.Errorf("DependencyUpdateTool() got Score = %v, want %v for %v", got.Score, tt.want.Score, tt.name) } - if tt.err && got.Error2 == nil { - t.Errorf("DependencyUpdateTool() error = %v, want %v for %v", got.Error2, tt.want.Error2, tt.name) + if tt.err && got.Error == nil { + t.Errorf("DependencyUpdateTool() error = %v, want %v for %v", got.Error, tt.want.Error, tt.name) return } diff --git a/checks/evaluation/webhooks_test.go b/checks/evaluation/webhooks_test.go index 340e68ee1866..0f71f01207f0 100644 --- a/checks/evaluation/webhooks_test.go +++ b/checks/evaluation/webhooks_test.go @@ -139,8 +139,8 @@ func TestWebhooks(t *testing.T) { t.Parallel() got := Webhooks(tt.args.name, tt.args.dl, tt.args.r) if tt.wantErr { - if got.Error2 == nil { - t.Errorf("Webhooks() error = %v, wantErr %v", got.Error2, tt.wantErr) + if got.Error == nil { + t.Errorf("Webhooks() error = %v, wantErr %v", got.Error, tt.wantErr) } } else { if got.Score != tt.want.Score { diff --git a/checks/fuzzing_test.go b/checks/fuzzing_test.go index 174a2de4d1e8..7fa538a54654 100644 --- a/checks/fuzzing_test.go +++ b/checks/fuzzing_test.go @@ -295,8 +295,8 @@ func TestFuzzing(t *testing.T) { } result := Fuzzing(&req) - if (result.Error2 != nil) != tt.wantErr { - t.Errorf("Fuzzing() error = %v, wantErr %v", result.Error2, tt.wantErr) + if (result.Error != nil) != tt.wantErr { + t.Errorf("Fuzzing() error = %v, wantErr %v", result.Error, tt.wantErr) return } diff --git a/checks/maintained_test.go b/checks/maintained_test.go index 0edfd3f8141f..e7fb10998fd1 100644 --- a/checks/maintained_test.go +++ b/checks/maintained_test.go @@ -345,7 +345,7 @@ func Test_Maintained(t *testing.T) { res := Maintained(&req) if tt.err != nil { - if res.Error2 == nil { + if res.Error == nil { t.Errorf("Expected error %v, got nil", tt.err) } // return as we don't need to check the rest of the fields. diff --git a/checks/pinned_dependencies_test.go b/checks/pinned_dependencies_test.go index c68cc3825527..2d9f120d095f 100644 --- a/checks/pinned_dependencies_test.go +++ b/checks/pinned_dependencies_test.go @@ -128,8 +128,8 @@ func TestGithubWorkflowPinning(t *testing.T) { s, e := testIsGitHubActionsWorkflowPinned(p, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -221,8 +221,8 @@ func TestNonGithubWorkflowPinning(t *testing.T) { s, e := testIsGitHubActionsWorkflowPinned(p, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -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, }, @@ -268,8 +268,8 @@ func TestGithubWorkflowPkgManagerPinning(t *testing.T) { s, e := testValidateGitHubWorkflowScriptFreeOfInsecureDownloads(p, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { @@ -392,8 +392,8 @@ func TestDockerfilePinning(t *testing.T) { dl := scut.TestDetailLogger{} s, e := testValidateDockerfileIsPinned(tt.filename, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -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, + }, }, }, } @@ -781,8 +791,8 @@ func TestDockerfilePinningWihoutHash(t *testing.T) { dl := scut.TestDetailLogger{} s, e := testValidateDockerfileIsPinned(tt.filename, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -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, }, @@ -970,8 +980,8 @@ func TestDockerfileScriptDownload(t *testing.T) { dl := scut.TestDetailLogger{} s, e := testValidateDockerfileIsFreeOfInsecureDownloads(tt.filename, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -1013,8 +1023,8 @@ func TestDockerfileScriptDownloadInfo(t *testing.T) { dl := scut.TestDetailLogger{} s, e := testValidateDockerfileIsFreeOfInsecureDownloads(tt.filename, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -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, }, @@ -1123,8 +1133,8 @@ func TestShellScriptDownload(t *testing.T) { dl := scut.TestDetailLogger{} s, e := testValidateShellScriptIsFreeOfInsecureDownloads(tt.filename, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -1178,8 +1188,8 @@ func TestShellScriptDownloadPinned(t *testing.T) { dl := scut.TestDetailLogger{} s, e := testValidateShellScriptIsFreeOfInsecureDownloads(tt.filename, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() @@ -1257,8 +1267,8 @@ func TestGitHubWorflowRunDownload(t *testing.T) { s, e := testValidateGitHubWorkflowScriptFreeOfInsecureDownloads(p, content, &dl) actual := checker.CheckResult{ - Score: s, - Error2: e, + Score: s, + Error: e, } if !scut.ValidateTestReturn(t, tt.name, &tt.expected, &actual, &dl) { t.Fail() diff --git a/checks/raw/cii_best_practices.go b/checks/raw/cii_best_practices.go new file mode 100644 index 000000000000..fb2aee36fe3e --- /dev/null +++ b/checks/raw/cii_best_practices.go @@ -0,0 +1,55 @@ +// Copyright 2022 Security Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package raw + +import ( + "errors" + "fmt" + + "github.com/ossf/scorecard/v4/checker" + "github.com/ossf/scorecard/v4/clients" +) + +var errEmptyClient = errors.New("CII client is nil") + +// CIIBestPractices retrieves the raw data for the CIIBestPractices check. +func CIIBestPractices(c *checker.CheckRequest) (checker.CIIBestPracticesData, error) { + var results checker.CIIBestPracticesData + if c.CIIClient == nil { + return results, fmt.Errorf("%w", errEmptyClient) + } + + badge, err := c.CIIClient.GetBadgeLevel(c.Ctx, c.Repo.URI()) + if err != nil { + return results, fmt.Errorf("%w", err) + } + + switch badge { + case clients.NotFound: + results.Badge = checker.CIIBadgeNotFound + case clients.InProgress: + results.Badge = checker.CIIBadgeInProgress + case clients.Passing: + results.Badge = checker.CIIBadgePassing + case clients.Silver: + results.Badge = checker.CIIBadgeSilver + case clients.Gold: + results.Badge = checker.CIIBadgeGold + case clients.Unknown: + results.Badge = checker.CIIBadgeUnknown + } + + return results, nil +} diff --git a/checks/shell_download_validate.go b/checks/shell_download_validate.go index 85fb589825ec..3e9c28c51076 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/signed_releases_test.go b/checks/signed_releases_test.go index dd9bb730e0e7..08b1fc6c26e5 100644 --- a/checks/signed_releases_test.go +++ b/checks/signed_releases_test.go @@ -359,9 +359,9 @@ func TestSignedRelease(t *testing.T) { name: "Error getting releases", err: errors.New("Error getting releases"), expected: checker.CheckResult{ - Pass: false, - Score: -1, - Error2: errors.New("Error getting releases"), + Pass: false, + Score: -1, + Error: errors.New("Error getting releases"), }, }, } @@ -390,7 +390,7 @@ func TestSignedRelease(t *testing.T) { res := SignedReleases(&req) if tt.err != nil { - if res.Error2 == nil { + if res.Error == nil { t.Errorf("Expected error %v, got nil", tt.err) } // return as we don't need to check the rest of the fields. diff --git a/checks/testdata/.github/workflows/github-workflow-pkg-managers.yaml b/checks/testdata/.github/workflows/github-workflow-pkg-managers.yaml index 7a0fc4919d2b..42136653b0fe 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 4ba72d17d617..d3ac28070f5b 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 eb177887a023..29cb5cdc5ae7 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 15215cf578b2..8b5ab645fa9f 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 diff --git a/checks/webhook_test.go b/checks/webhook_test.go index 4c601c839afc..e96f9122c6d6 100644 --- a/checks/webhook_test.go +++ b/checks/webhook_test.go @@ -123,7 +123,7 @@ func TestWebhooks(t *testing.T) { } res := WebHooks(&req) if tt.err != nil { - if res.Error2 == nil { + if res.Error == nil { t.Errorf("Expected error %v, got nil", tt.err) } // return as we don't need to check the rest of the fields. diff --git a/cron/k8s/transfer-raw.yaml b/cron/k8s/transfer-raw.yaml index faff1971b15b..f0f0e7fdb863 100644 --- a/cron/k8s/transfer-raw.yaml +++ b/cron/k8s/transfer-raw.yaml @@ -34,8 +34,8 @@ spec: requests: memory: 1Gi env: - - name: RAW_SCORECARD_BIGQUERY_TABLE + - name: SCORECARD_BIGQUERY_TABLE value: "scorecard-rawdata" - - name: RAW_SCORECARD_DATA_BUCKET_URL + - name: SCORECARD_DATA_BUCKET_URL value: "gs://ossf-scorecard-rawdata" restartPolicy: OnFailure diff --git a/cron/k8s/transfer.release-raw.yaml b/cron/k8s/transfer.release-raw.yaml index 3e285f0f133d..93441fe3c070 100644 --- a/cron/k8s/transfer.release-raw.yaml +++ b/cron/k8s/transfer.release-raw.yaml @@ -30,9 +30,9 @@ spec: image: gcr.io/openssf/scorecard-bq-transfer:latest imagePullPolicy: Always env: - - name: RAW_SCORECARD_DATA_BUCKET_URL + - name: SCORECARD_DATA_BUCKET_URL value: "gs://ossf-scorecard-rawdata-releasetest" - - name: RAW_SCORECARD_BIGQUERY_TABLE + - name: SCORECARD_BIGQUERY_TABLE value: "scorecard-rawdata-releasetest" - name: SCORECARD_COMPLETION_THRESHOLD value: "0.9" diff --git a/cron/worker/main.go b/cron/worker/main.go index a491da2be687..9d9ca8da8ea3 100644 --- a/cron/worker/main.go +++ b/cron/worker/main.go @@ -118,10 +118,10 @@ func processRequest(ctx context.Context, } for checkIndex := range result.Checks { check := &result.Checks[checkIndex] - if !errors.Is(check.Error2, sce.ErrScorecardInternal) { + if !errors.Is(check.Error, sce.ErrScorecardInternal) { continue } - errorMsg := fmt.Sprintf("check %s has a runtime error: %v", check.Name, check.Error2) + errorMsg := fmt.Sprintf("check %s has a runtime error: %v", check.Name, check.Error) if !(*ignoreRuntimeErrors) { // nolint: goerr113 return errors.New(errorMsg) diff --git a/e2e/binary_artifacts_test.go b/e2e/binary_artifacts_test.go index 57fb842b8e26..807d739c1f1e 100644 --- a/e2e/binary_artifacts_test.go +++ b/e2e/binary_artifacts_test.go @@ -86,7 +86,6 @@ var _ = Describe("E2E TEST:"+checks.CheckBinaryArtifacts, func() { result := checks.BinaryArtifacts(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "binary artifacts", &expected, &result, &dl)).Should(BeTrue()) @@ -117,7 +116,6 @@ var _ = Describe("E2E TEST:"+checks.CheckBinaryArtifacts, func() { result := checks.BinaryArtifacts(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "binary artifacts", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/branch_protection_test.go b/e2e/branch_protection_test.go index 39fbb11550a1..a42ddf2d8157 100644 --- a/e2e/branch_protection_test.go +++ b/e2e/branch_protection_test.go @@ -54,7 +54,6 @@ var _ = Describe("E2E TEST PAT:"+checks.CheckBranchProtection, func() { result := checks.BranchProtection(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. @@ -86,7 +85,6 @@ var _ = Describe("E2E TEST PAT:"+checks.CheckBranchProtection, func() { result := checks.BranchProtection(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. @@ -118,7 +116,6 @@ var _ = Describe("E2E TEST PAT:"+checks.CheckBranchProtection, func() { result := checks.BranchProtection(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. @@ -146,9 +143,9 @@ var _ = Describe("E2E TEST GITHUB_TOKEN:"+checks.CheckBranchProtection, func() { } result := checks.BranchProtection(&req) + Expect(result.Error).ShouldNot(BeNil()) // There should be an error with the GITHUB_TOKEN, until it's supported // byt GitHub. - Expect(result.Error).ShouldNot(BeNil()) Expect(repoClient.Close()).Should(BeNil()) }) }) diff --git a/e2e/cii_best_practices_test.go b/e2e/cii_best_practices_test.go index e83f2b107239..7889b51c1b74 100644 --- a/e2e/cii_best_practices_test.go +++ b/e2e/cii_best_practices_test.go @@ -52,7 +52,6 @@ var _ = Describe("E2E TEST:"+checks.CheckCIIBestPractices, func() { result := checks.CIIBestPractices(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "passing badge", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/contributors_test.go b/e2e/contributors_test.go index 5b029c75328b..1d93e47d41bd 100644 --- a/e2e/contributors_test.go +++ b/e2e/contributors_test.go @@ -52,7 +52,6 @@ var _ = Describe("E2E TEST:"+checks.CheckContributors, func() { result := checks.Contributors(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "several contributors", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/dangerous_workflow_test.go b/e2e/dangerous_workflow_test.go index e56bd664e637..840244632791 100644 --- a/e2e/dangerous_workflow_test.go +++ b/e2e/dangerous_workflow_test.go @@ -56,7 +56,6 @@ var _ = Describe("E2E TEST:"+checks.CheckTokenPermissions, func() { // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "dangerous workflow", &expected, &result, &dl)).Should(BeTrue()) @@ -85,7 +84,6 @@ var _ = Describe("E2E TEST:"+checks.CheckTokenPermissions, func() { // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "dangerous workflow", &expected, &result, &dl)).Should(BeTrue()) @@ -126,7 +124,6 @@ var _ = Describe("E2E TEST:"+checks.CheckTokenPermissions, func() { // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "dangerous workflow", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/dependency_update_tool_test.go b/e2e/dependency_update_tool_test.go index c583f5ee94df..6e2befcd2c57 100644 --- a/e2e/dependency_update_tool_test.go +++ b/e2e/dependency_update_tool_test.go @@ -56,7 +56,6 @@ var _ = Describe("E2E TEST:"+checks.CheckDependencyUpdateTool, func() { result := checks.DependencyUpdateTool(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "dependabot", &expected, &result, &dl)).Should(BeTrue()) @@ -86,7 +85,6 @@ var _ = Describe("E2E TEST:"+checks.CheckDependencyUpdateTool, func() { result := checks.DependencyUpdateTool(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "renovabot", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/license_test.go b/e2e/license_test.go index 8efa1f530033..2a0f2e701c51 100644 --- a/e2e/license_test.go +++ b/e2e/license_test.go @@ -54,7 +54,6 @@ var _ = Describe("E2E TEST:"+checks.CheckLicense, func() { } result := checks.License(&req) - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) Expect(scut.ValidateTestReturn(nil, "license found", &expected, &result, @@ -82,7 +81,6 @@ var _ = Describe("E2E TEST:"+checks.CheckLicense, func() { } result := checks.License(&req) - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) Expect(scut.ValidateTestReturn(nil, "license found", &expected, &result, @@ -122,7 +120,6 @@ var _ = Describe("E2E TEST:"+checks.CheckLicense, func() { } result := checks.License(&req) - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) Expect(scut.ValidateTestReturn(nil, "license found", &expected, &result, diff --git a/e2e/maintained_test.go b/e2e/maintained_test.go index 680e2ae3737a..0292fb351d7c 100644 --- a/e2e/maintained_test.go +++ b/e2e/maintained_test.go @@ -52,7 +52,6 @@ var _ = Describe("E2E TEST:"+checks.CheckMaintained, func() { result := checks.Maintained(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "active repo", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/permissions_test.go b/e2e/permissions_test.go index 4d6a9f937d94..0c59f3c3d7c2 100644 --- a/e2e/permissions_test.go +++ b/e2e/permissions_test.go @@ -56,7 +56,6 @@ var _ = Describe("E2E TEST:"+checks.CheckTokenPermissions, func() { // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "token permissions", &expected, &result, &dl)).Should(BeTrue()) @@ -86,7 +85,6 @@ var _ = Describe("E2E TEST:"+checks.CheckTokenPermissions, func() { // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "token permissions", &expected, &result, &dl)).Should(BeTrue()) @@ -128,7 +126,6 @@ var _ = Describe("E2E TEST:"+checks.CheckTokenPermissions, func() { // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "token permissions", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/sast_test.go b/e2e/sast_test.go index a5cef62a1576..ed21d6d0ba6a 100644 --- a/e2e/sast_test.go +++ b/e2e/sast_test.go @@ -52,7 +52,6 @@ var _ = Describe("E2E TEST:"+checks.CheckSAST, func() { result := checks.SAST(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "sast used", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/security_policy_test.go b/e2e/security_policy_test.go index 5c22803fffd1..8c856e21220f 100644 --- a/e2e/security_policy_test.go +++ b/e2e/security_policy_test.go @@ -56,7 +56,6 @@ var _ = Describe("E2E TEST:"+checks.CheckSecurityPolicy, func() { result := checks.SecurityPolicy(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "policy found", &expected, &result, &dl)).Should(BeTrue()) @@ -86,7 +85,6 @@ var _ = Describe("E2E TEST:"+checks.CheckSecurityPolicy, func() { result := checks.SecurityPolicy(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "policy found", &expected, &result, &dl)).Should(BeTrue()) @@ -116,7 +114,6 @@ var _ = Describe("E2E TEST:"+checks.CheckSecurityPolicy, func() { result := checks.SecurityPolicy(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "policy found", &expected, &result, &dl)).Should(BeTrue()) @@ -146,7 +143,6 @@ var _ = Describe("E2E TEST:"+checks.CheckSecurityPolicy, func() { result := checks.SecurityPolicy(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "policy found", &expected, &result, &dl)).Should(BeTrue()) @@ -187,7 +183,6 @@ var _ = Describe("E2E TEST:"+checks.CheckSecurityPolicy, func() { result := checks.SecurityPolicy(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "policy found", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/signedreleases_test.go b/e2e/signedreleases_test.go index 1c1f23322066..098a1997f5e5 100644 --- a/e2e/signedreleases_test.go +++ b/e2e/signedreleases_test.go @@ -52,7 +52,6 @@ var _ = Describe("E2E TEST:"+checks.CheckSignedReleases, func() { result := checks.SignedReleases(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "verified release", &expected, &result, &dl)).Should(BeTrue()) diff --git a/e2e/vulnerabilities_test.go b/e2e/vulnerabilities_test.go index 806e27384dfd..729cc6e5ff1b 100644 --- a/e2e/vulnerabilities_test.go +++ b/e2e/vulnerabilities_test.go @@ -55,7 +55,6 @@ var _ = Describe("E2E TEST:"+checks.CheckVulnerabilities, func() { result := checks.Vulnerabilities(&req) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeTrue()) // New version. Expect(scut.ValidateTestReturn(nil, "no osv vulnerabilities", &expected, &result, &dl)).Should(BeTrue()) @@ -87,7 +86,6 @@ var _ = Describe("E2E TEST:"+checks.CheckVulnerabilities, func() { result := checks.Vulnerabilities(&checkRequest) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "osv vulnerabilities", &expected, &result, &dl)).Should(BeTrue()) @@ -118,7 +116,6 @@ var _ = Describe("E2E TEST:"+checks.CheckVulnerabilities, func() { result := checks.Vulnerabilities(&checkRequest) // UPGRADEv2: to remove. // Old version. - Expect(result.Error).Should(BeNil()) Expect(result.Pass).Should(BeFalse()) // New version. Expect(scut.ValidateTestReturn(nil, "osv vulnerabilities", &expected, &result, &dl)).Should(BeTrue()) diff --git a/pkg/json_raw_results.go b/pkg/json_raw_results.go index c4c2f2d3b35a..525258acdf68 100644 --- a/pkg/json_raw_results.go +++ b/pkg/json_raw_results.go @@ -132,6 +132,10 @@ type jsonReleaseAsset struct { URL string `json:"url"` } +type jsonOssfBestPractices struct { + Badge string `json:"badge"` +} + //nolint type jsonLicense struct { File jsonFile `json:"file"` @@ -172,7 +176,9 @@ type jsonRawResults struct { Licenses []jsonLicense `json:"licenses"` // List of recent issues. RecentIssues []jsonIssue `json:"issues"` - // List of vulnerabilities. + // OSSF best practices badge. + OssfBestPractices jsonOssfBestPractices `json:"openssf-best-practices-badge"` + // Vulnerabilities. DatabaseVulnerabilities []jsonDatabaseVulnerability `json:"database-vulnerabilities"` // List of binaries found in the repo. Binaries []jsonFile `json:"binaries"` @@ -377,6 +383,12 @@ func (r *jsonScorecardRawResult) setDefaultCommitData(commits []checker.DefaultB return nil } +//nolint:unparam +func (r *jsonScorecardRawResult) addOssfBestPracticesRawResults(cbp *checker.CIIBestPracticesData) error { + r.Results.OssfBestPractices.Badge = string(cbp.Badge) + return nil +} + func (r *jsonScorecardRawResult) addCodeReviewRawResults(cr *checker.CodeReviewData) error { return r.setDefaultCommitData(cr.DefaultBranchCommits) } @@ -526,7 +538,12 @@ func (r *jsonScorecardRawResult) fillJSONRawResults(raw *checker.RawResults) err return sce.WithMessage(sce.ErrScorecardInternal, err.Error()) } - // Dangerous workflow. + // CII-Best-Practices. + if err := r.addOssfBestPracticesRawResults(&raw.CIIBestPracticesResults); err != nil { + return sce.WithMessage(sce.ErrScorecardInternal, err.Error()) + } + + // Dangerous workflow. if err := r.addDangerousWorkflowRawResults(&raw.DangerousWorkflowResults); err != nil { return sce.WithMessage(sce.ErrScorecardInternal, err.Error()) }