This commit is contained in:
laurentsimon 2022-06-29 10:10:15 -07:00 committed by GitHub
parent 6a032a3019
commit 3957460c2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 99 deletions

View File

@ -23,6 +23,7 @@ import (
"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/checks/fileparser"
sce "github.com/ossf/scorecard/v4/errors"
"github.com/ossf/scorecard/v4/remediation"
)
// CheckTokenPermissions is the exported name for Token-Permissions check.
@ -83,7 +84,7 @@ func TokenPermissions(c *checker.CheckRequest) checker.CheckResult {
workflows: make(map[string]permissions),
}
if err := remdiationSetup(c); err != nil {
if err := remediation.Setup(c); err != nil {
createResultForLeastPrivilegeTokens(data, err)
}
@ -167,7 +168,7 @@ func validatePermission(permissionKey permission, permissionValue *actionlint.Pe
Offset: lineNumber,
Text: fmt.Sprintf("%s '%v' permission set to '%v'", permLevel, permissionKey, val),
Snippet: val,
Remediation: createWorkflowPermissionRemediation(path),
Remediation: remediation.CreateWorkflowPermissionRemediation(path),
})
recordPermissionWrite(pPermissions, permissionKey)
} else {
@ -179,7 +180,7 @@ func validatePermission(permissionKey permission, permissionValue *actionlint.Pe
Offset: lineNumber,
Text: fmt.Sprintf("%s '%v' permission set to '%v'", permLevel, permissionKey, val),
Snippet: val,
Remediation: createWorkflowPermissionRemediation(path),
Remediation: remediation.CreateWorkflowPermissionRemediation(path),
})
}
return nil
@ -255,7 +256,7 @@ func validatePermissions(permissions *actionlint.Permissions, permLevel, path st
Offset: lineNumber,
Text: fmt.Sprintf("%s permissions set to '%v'", permLevel, val),
Snippet: val,
Remediation: createWorkflowPermissionRemediation(path),
Remediation: remediation.CreateWorkflowPermissionRemediation(path),
})
recordAllPermissionsWrite(pdata, permLevel, path)
return nil
@ -267,7 +268,7 @@ func validatePermissions(permissions *actionlint.Permissions, permLevel, path st
Offset: lineNumber,
Text: fmt.Sprintf("%s permissions set to '%v'", permLevel, val),
Snippet: val,
Remediation: createWorkflowPermissionRemediation(path),
Remediation: remediation.CreateWorkflowPermissionRemediation(path),
})
} else /* scopeIsSet == true */ if err := validateMapPermissions(permissions.Scopes,
permLevel, path, dl, getWritePermissionsMap(pdata, path, permLevel), ignoredPermissions); err != nil {
@ -286,7 +287,7 @@ func validateTopLevelPermissions(workflow *actionlint.Workflow, path string,
Type: checker.FileTypeSource,
Offset: checker.OffsetDefault,
Text: fmt.Sprintf("no %s permission defined", topLevelPermission),
Remediation: createWorkflowPermissionRemediation(path),
Remediation: remediation.CreateWorkflowPermissionRemediation(path),
})
recordAllPermissionsWrite(pdata, topLevelPermission, path)
return nil
@ -310,7 +311,7 @@ func validatejobLevelPermissions(workflow *actionlint.Workflow, path string,
Type: checker.FileTypeSource,
Offset: fileparser.GetLineNumber(job.Pos),
Text: fmt.Sprintf("no %s permission defined", jobLevelPermission),
Remediation: createWorkflowPermissionRemediation(path),
Remediation: remediation.CreateWorkflowPermissionRemediation(path),
})
recordAllPermissionsWrite(pdata, jobLevelPermission, path)
continue
@ -615,7 +616,7 @@ func isReleasingWorkflow(workflow *actionlint.Workflow, fp string, dl checker.De
}
// TODO: remove when migrated to raw results.
// Should be using the definition in raw/packaging.go
// Should be using the definition in raw/packaging.go.
func isPackagingWorkflow(workflow *actionlint.Workflow, fp string, dl checker.DetailLogger) bool {
jobMatchers := []fileparser.JobMatcher{
{

View File

@ -42,7 +42,7 @@ type filesWithPatternStr struct {
type languageFuzzConfig struct {
URL, Desc *string
filePattern, funcPattern, Name string
//TODO: add more language fuzzing-related fields.
// TODO: add more language fuzzing-related fields.
}
// Contains fuzzing speficications for programming languages.
@ -190,7 +190,8 @@ func checkFuzzFunc(c *checker.CheckRequest, lang clients.LanguageName) (bool, []
// used for matching fuzz functions in the file content,
// and return a list of files (or nil for not found).
var getFuzzFunc fileparser.DoWhileTrueOnFileContent = func(
path string, content []byte, args ...interface{}) (bool, error) {
path string, content []byte, args ...interface{},
) (bool, error) {
if len(args) != 1 {
return false, fmt.Errorf("getFuzzFunc requires exactly one argument: %w", errInvalidArgLength)
}

View File

@ -1,88 +0,0 @@
// 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 checks
import (
"errors"
"fmt"
"strings"
"sync"
"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/clients"
)
var (
remediationBranch string
remediationRepo string
remediationOnce *sync.Once
remediationSetupErr error
)
var (
workflowText = "update your workflow using https://app.stepsecurity.io/secureworkflow/%s/%s/%s?enable=%s"
//nolint
workflowMarkdown = "update your workflow using [https://app.stepsecurity.io](https://app.stepsecurity.io/secureworkflow/%s/%s/%s?enable=%s)"
)
//nolint:gochecknoinits
func init() {
remediationOnce = new(sync.Once)
}
func remdiationSetup(c *checker.CheckRequest) error {
remediationOnce.Do(func() {
// Get the branch for remediation.
b, err := c.RepoClient.GetDefaultBranch()
if err != nil {
if !errors.Is(err, clients.ErrUnsupportedFeature) {
remediationSetupErr = err
}
return
}
if b.Name != nil {
remediationBranch = *b.Name
uri := c.Repo.URI()
parts := strings.Split(uri, "/")
if len(parts) != 3 {
remediationSetupErr = fmt.Errorf("%w: %s", errInvalidArgLength, uri)
return
}
remediationRepo = fmt.Sprintf("%s/%s", parts[1], parts[2])
}
})
return remediationSetupErr
}
func createWorkflowPermissionRemediation(filepath string) *checker.Remediation {
return createWorkflowRemediation(filepath, "permissions")
}
func createWorkflowRemediation(path, t string) *checker.Remediation {
p := strings.TrimPrefix(path, ".github/workflows/")
if remediationBranch == "" || remediationRepo == "" {
return nil
}
text := fmt.Sprintf(workflowText, remediationRepo, p, remediationBranch, t)
markdown := fmt.Sprintf(workflowMarkdown, remediationRepo, p, remediationBranch, t)
return &checker.Remediation{
HelpText: text,
HelpMarkdown: markdown,
}
}

View File

@ -57,6 +57,30 @@ var _ = Describe("E2E TEST:"+checks.CheckTokenPermissions, func() {
Expect(scut.ValidateTestReturn(nil, "token permissions", &expected, &result, &dl)).Should(BeTrue())
Expect(repoClient.Close()).Should(BeNil())
})
It("Should return token permission works on empty repo", func() {
dl := scut.TestDetailLogger{}
repo, err := githubrepo.MakeGithubRepo("ossf-tests/scorecard-empty-repo")
Expect(err).Should(BeNil())
repoClient := githubrepo.CreateGithubRepoClient(context.Background(), logger)
err = repoClient.InitRepo(repo, clients.HeadSHA)
Expect(err).Should(BeNil())
req := checker.CheckRequest{
Ctx: context.Background(),
RepoClient: repoClient,
Repo: repo,
Dlogger: &dl,
}
expected := scut.TestReturn{
Error: nil,
Score: checker.MaxResultScore,
NumberOfWarn: 0,
NumberOfInfo: 0,
NumberOfDebug: 0,
}
result := checks.TokenPermissions(&req)
Expect(scut.ValidateTestReturn(nil, "token permissions", &expected, &result, &dl)).Should(BeTrue())
Expect(repoClient.Close()).Should(BeNil())
})
It("Should return token permission at commit", func() {
dl := scut.TestDetailLogger{}
repo, err := githubrepo.MakeGithubRepo("ossf-tests/scorecard-check-token-permissions-e2e")

View File

@ -55,7 +55,8 @@ func Setup(c *checker.CheckRequest) error {
}
return
}
if b.Name != nil {
if b != nil && b.Name != nil {
branch = *b.Name
uri := c.Repo.URI()
parts := strings.Split(uri, "/")