From ec6174145805ed02a04e3b1b875aa14b0d065100 Mon Sep 17 00:00:00 2001 From: Azeem Shaikh Date: Wed, 17 Nov 2021 21:00:06 -0800 Subject: [PATCH] More nilptr issues --- checks/pinned_dependencies.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/checks/pinned_dependencies.go b/checks/pinned_dependencies.go index 73080c08be0..43ee0c95454 100644 --- a/checks/pinned_dependencies.go +++ b/checks/pinned_dependencies.go @@ -454,6 +454,7 @@ func testValidateGitHubWorkflowScriptFreeOfInsecureDownloads(pathfn string, // validateGitHubWorkflowIsFreeOfInsecureDownloads checks if the workflow file downloads dependencies that are unpinned. // Returns true if the check should continue executing after this file. +// nolint: gocognit func validateGitHubWorkflowIsFreeOfInsecureDownloads(pathfn string, content []byte, dl checker.DetailLogger, data fileparser.FileCbData) (bool, error) { if !fileparser.IsWorkflowFile(pathfn) { @@ -477,14 +478,31 @@ func validateGitHubWorkflowIsFreeOfInsecureDownloads(pathfn string, content []by githubVarRegex := regexp.MustCompile(`{{[^{}]*}}`) validated := true scriptContent := "" - for _, job := range workflow.Jobs { + for jobName, job := range workflow.Jobs { + jobName := jobName job := job + if len(fileparser.GetJobName(job)) > 0 { + jobName = fileparser.GetJobName(job) + } for _, step := range job.Steps { step := step if !fileparser.IsStepExecKind(step, actionlint.ExecKindRun) { continue } + execRun, ok := step.Exec.(*actionlint.ExecRun) + if !ok { + stepName := fileparser.GetStepName(step) + return false, sce.WithMessage(sce.ErrScorecardInternal, + fmt.Sprintf("unable to parse step '%v' for job '%v'", jobName, stepName)) + } + + if execRun == nil || execRun.Run == nil { + // Cannot check further, continue. + continue + } + + run := execRun.Run.Value // https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun. shell, err := fileparser.GetShellForStep(step, job) if err != nil { @@ -495,7 +513,6 @@ func validateGitHubWorkflowIsFreeOfInsecureDownloads(pathfn string, content []by continue } - run := step.Exec.(*actionlint.ExecRun).Run.Value // We replace the `${{ github.variable }}` to avoid shell parsing failures. script := githubVarRegex.ReplaceAll([]byte(run), []byte("GITHUB_REDACTED_VAR")) scriptContent = fmt.Sprintf("%v\n%v", scriptContent, string(script)) @@ -561,6 +578,8 @@ func validateGitHubActionWorkflow(pathfn string, content []byte, hashRegex := regexp.MustCompile(`^.*@[a-f\d]{40,}`) for jobName, job := range workflow.Jobs { + jobName := jobName + job := job if len(fileparser.GetJobName(job)) > 0 { jobName = fileparser.GetJobName(job) } @@ -574,6 +593,11 @@ func validateGitHubActionWorkflow(pathfn string, content []byte, return false, sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("unable to parse step '%v' for job '%v'", jobName, stepName)) } + + if execAction == nil || execAction.Uses == nil { + // Cannot check further, continue. + continue + } // Ensure a hash at least as large as SHA1 is used (40 hex characters). // Example: action-name@hash match := hashRegex.Match([]byte(execAction.Uses.Value))