diff --git a/README.md b/README.md index 32b40ae21eb..f2bcb466983 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,6 @@ Packaging | Does the project build and publish official packag SAST | Does the project use static code analysis tools, e.g. [CodeQL](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/enabling-code-scanning-for-a-repository#enabling-code-scanning-using-actions), [SonarCloud](https://sonarcloud.io)? Security-Policy | Does the project contain a [security policy](https://docs.github.com/en/free-pro-team@latest/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository)? Signed-Releases | Does the project cryptographically [sign releases](https://wiki.debian.org/Creating%20signed%20GitHub%20releases)? -Signed-Tags | Does the project cryptographically sign release tags? Token-Permissions | Does the project declare GitHub workflow tokens as [read only](https://docs.github.com/en/actions/reference/authentication-in-a-workflow)? Vulnerabilities | Does the project have unfixed vulnerabilities? Uses the [OSV service](https://osv.dev). @@ -85,7 +84,6 @@ The program can run using just one argument, the URL of the repo: ```shell $ go get github.com/ossf/scorecard/v2 $ scorecard --repo=github.com/kubernetes/kubernetes -Starting [Signed-Tags] Starting [Automatic-Dependency-Update] Starting [Frozen-Deps] Starting [Fuzzing] @@ -116,7 +114,6 @@ Finished [Automatic-Dependency-Update] Finished [Frozen-Deps] Finished [Fuzzing] Finished [Pull-Requests] -Finished [Signed-Tags] Finished [Branch-Protection] Finished [Code-Review] Finished [SAST] @@ -139,7 +136,6 @@ Pull-Requests: Pass 10 SAST: Fail 10 Security-Policy: Fail 5 Signed-Releases: Fail 10 -Signed-Tags: Fail 10 Token-Permissions: Pass 10 ``` @@ -186,7 +182,6 @@ Starting [Pull-Requests] Starting [SAST] Starting [Security-Policy] Starting [Signed-Releases] -Starting [Signed-Tags] Finished [Signed-Releases] Finished [Fuzzing] Finished [CII-Best-Practices] @@ -197,7 +192,6 @@ Finished [SAST] Finished [Code-Review] Finished [Branch-Protection] Finished [Frozen-Deps] -Finished [Signed-Tags] Finished [Active] Finished [Pull-Requests] Finished [Contributors] @@ -217,7 +211,6 @@ Pull-Requests: Fail 9 SAST: Fail 10 Security-Policy: Pass 10 Signed-Releases: Fail 0 -Signed-Tags: Fail 10 ``` ### Running specific checks diff --git a/checks/signed_tags.go b/checks/signed_tags.go deleted file mode 100644 index 24220b72fcc..00000000000 --- a/checks/signed_tags.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2020 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 checks - -import ( - "fmt" - - "github.com/shurcooL/githubv4" - - "github.com/ossf/scorecard/v2/checker" - sce "github.com/ossf/scorecard/v2/errors" -) - -const ( - // CheckSignedTags is the registered name for SignedTags. - CheckSignedTags = "Signed-Tags" - tagLookBack = 5 -) - -//nolint:gochecknoinits -func init() { - registerCheck(CheckSignedTags, SignedTags) -} - -// SignedTags runs Signed-Tags check. -func SignedTags(c *checker.CheckRequest) checker.CheckResult { - type ref struct { - Name githubv4.String - Target struct { - Oid githubv4.String - } - } - var query struct { - Repository struct { - Refs struct { - Nodes []ref - } `graphql:"refs(refPrefix: \"refs/tags/\", last: $count)"` - } `graphql:"repository(owner: $owner, name: $name)"` - } - - variables := map[string]interface{}{ - "owner": githubv4.String(c.Owner), - "name": githubv4.String(c.Repo), - "count": githubv4.Int(tagLookBack), - } - - if err := c.GraphClient.Query(c.Ctx, &query, variables); err != nil { - e := sce.Create(sce.ErrScorecardInternal, fmt.Sprintf("GraphClient.Query: %v", err)) - return checker.CreateRuntimeErrorResult(CheckSignedTags, e) - } - totalTags := 0 - totalSigned := 0 - for _, t := range query.Repository.Refs.Nodes { - sha := string(t.Target.Oid) - totalTags++ - gt, _, err := c.Client.Git.GetTag(c.Ctx, c.Owner, c.Repo, sha) - if err != nil { - c.Dlogger.Debug("unable to find the annotated commit: %s", sha) - continue - } - if gt.GetVerification().GetVerified() { - c.Dlogger.Debug("signature verifies for tag: %s, commit: %s", t.Name, sha) - totalSigned++ - } else { - c.Dlogger.Debug("signature does not verify for tag: %s, commit: %s, reason: %s", - t.Name, sha, gt.GetVerification().GetReason()) - } - } - - if totalTags == 0 { - return checker.CreateInconclusiveResult(CheckSignedTags, "no tags found") - } - - // TODO: support package managers. - reason := fmt.Sprintf("%d out of %d tags have a verified signature", totalSigned, totalTags) - return checker.CreateProportionalScoreResult(CheckSignedTags, reason, totalSigned, totalTags) -} diff --git a/docs/checks.md b/docs/checks.md index c10105bcb3e..98d139d3a69 100644 --- a/docs/checks.md +++ b/docs/checks.md @@ -147,19 +147,6 @@ It works by looking for filenames: *.minisig (https://github.com/jedisct1/minisi - Attach the signature file next to the release archive. - For GitHub, check out the steps [here](https://wiki.debian.org/Creating%20signed%20GitHub%20releases). -## Signed-Tags - -This check looks for cryptographically signed tags in the last 5 tags. -Signed tags attest the author of a commit. A low score is considered 'Medium' risk. -The check does not verify the signature itself and currently relies on GitHub's verification. - -**Remediation steps** -- Generate a new signing key. -- Add your key to your source hosting provider. -- Configure your key and email in git. -- Publish the tag and then sign it with this key. -- For GitHub, check out the steps [here](https://docs.github.com/en/github/authenticating-to-github/signing-tags#further-reading). - ## Token-Permissions This check tries to determine if a project's GitHub workflows follow the principle of least privilege, i.e. if the GitHub tokens are set read-only by default. diff --git a/docs/checks/checks.yaml b/docs/checks/checks.yaml index bff326e1a48..b3bcb900d3d 100644 --- a/docs/checks/checks.yaml +++ b/docs/checks/checks.yaml @@ -278,22 +278,6 @@ checks: - >- For GitHub, check out the steps [here](https://wiki.debian.org/Creating%20signed%20GitHub%20releases). - Signed-Tags: - risk: Medium - description: >- - This check looks for cryptographically signed tags in the last 5 tags. - - Signed tags attest the author of a commit. A low score is considered 'Medium' risk. - - The check does not verify the signature itself and currently relies on GitHub's verification. - remediation: - - Generate a new signing key. - - Add your key to your source hosting provider. - - Configure your key and email in git. - - Publish the tag and then sign it with this key. - - >- - For GitHub, check out the steps - [here](https://docs.github.com/en/github/authenticating-to-github/signing-tags#further-reading). Token-Permissions: risk: High description: >- diff --git a/e2e/executable_test.go b/e2e/executable_test.go index a3158d0b656..893cfe62037 100644 --- a/e2e/executable_test.go +++ b/e2e/executable_test.go @@ -20,6 +20,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/ossf/scorecard/v2/checks" ) type scorecard struct { @@ -50,34 +52,29 @@ var _ = Describe("E2E TEST:executable", func() { for _, c := range data.Checks { switch c.CheckName { - case "Active": + case checks.CheckActive: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "Branch-Protection": + case checks.CheckBranchProtection: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "CI-Tests": + case checks.CheckCITests: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "CII-Best-Practices": + case checks.CheckCIIBestPractices: Expect(c.Pass).Should(BeFalse(), c.CheckName) - case "Code-Review": + case checks.CheckCodeReview: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "Contributors": + case checks.CheckContributors: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "Frozen-Deps": + case checks.CheckPinnedDependencies: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "Fuzzing": + case checks.CheckFuzzing: Expect(c.Pass).Should(BeFalse(), c.CheckName) - case "Packaging": - Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "Pull-Requests": + case checks.CheckPackaging: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "SAST": + case checks.CheckSAST: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "Security-Policy": + case checks.CheckSecurityPolicy: Expect(c.Pass).Should(BeTrue(), c.CheckName) - case "Signed-Releases": - Expect(c.Confidence).ShouldNot(Equal(10)) - Expect(c.Pass).Should(BeFalse(), c.CheckName) - case "Signed-Tags": + case checks.CheckSignedReleases: Expect(c.Confidence).ShouldNot(Equal(10)) Expect(c.Pass).Should(BeFalse(), c.CheckName) } diff --git a/e2e/signedtags_test.go b/e2e/signedtags_test.go deleted file mode 100644 index 35e10eb8000..00000000000 --- a/e2e/signedtags_test.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2021 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 e2e - -import ( - "context" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "github.com/ossf/scorecard/v2/checker" - "github.com/ossf/scorecard/v2/checks" - scut "github.com/ossf/scorecard/v2/utests" -) - -var _ = Describe("E2E TEST:Signedtags", func() { - Context("E2E TEST:Validating signed tags", func() { - It("Should return valid signed tags", func() { - dl := scut.TestDetailLogger{} - req := checker.CheckRequest{ - Ctx: context.Background(), - Client: ghClient, - HTTPClient: httpClient, - RepoClient: nil, - Owner: "ossf-tests", - Repo: "scorecard-check-signed-releases-e2e", - GraphClient: graphClient, - Dlogger: &dl, - } - expected := scut.TestReturn{ - Errors: nil, - Score: checker.MaxResultScore, - NumberOfWarn: 0, - NumberOfInfo: 0, - NumberOfDebug: 5, - } - result := checks.SignedTags(&req) - // UPGRADEv2: to remove. - // Old version. - Expect(result.Error).Should(BeNil()) - Expect(result.Pass).Should(BeTrue()) - // New version. - Expect(scut.ValidateTestReturn(nil, "verified tags", &expected, &result, &dl)).Should(BeTrue()) - }) - }) -})