Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentsimon committed Apr 26, 2022
1 parent a912c89 commit f2241ba
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 64 deletions.
25 changes: 14 additions & 11 deletions checker/raw_result.go
Expand Up @@ -283,24 +283,27 @@ type CIIBestPracticesData struct {
Badge CIIBadge
}

// DangerousWorkflowType represents a type of dangerous workflow.
type DangerousWorkflowType int

const (
// DangerousWorkflowScriptInjection represents a script injection.
DangerousWorkflowScriptInjection DangerousWorkflowType = iota
// DangerousWorkflowUntrustedCheckout represents an untrusted checkout.
DangerousWorkflowUntrustedCheckout
)

// DangerousWorkflowData contains raw results
// for dangerous workflow check.
type DangerousWorkflowData struct {
ScriptInjections []ScriptInjection
UntrustedCheckouts []UntrustedCheckout
// TODO: other
}

// UntrustedCheckout represents an untrusted checkout.
type UntrustedCheckout struct {
Job *WorkflowJob
File File
Workflows []Workflow
}

// ScriptInjection represents a script injection.
type ScriptInjection struct {
// Workflow represents a result for a workflow.
type Workflow struct {
Job *WorkflowJob
File File
Type DangerousWorkflowType
}

// WorkflowJob reprresents a workflow job.
Expand Down
28 changes: 13 additions & 15 deletions checks/evaluation/dangerous_workflow.go
Expand Up @@ -30,30 +30,28 @@ func DangerousWorkflow(name string, dl checker.DetailLogger,
return checker.CreateRuntimeErrorResult(name, e)
}

// Script injections.
for _, e := range r.ScriptInjections {
dl.Warn(&checker.LogMessage{
Path: e.File.Path,
Type: e.File.Type,
Offset: e.File.Offset,
Text: fmt.Sprintf("script injection with untrusted input '%v'", e.File.Snippet),
Snippet: e.File.Snippet,
})
}
for _, e := range r.Workflows {
var text string
switch e.Type {
case checker.DangerousWorkflowUntrustedCheckout:
text = fmt.Sprintf("untrusted code checkout '%v'", e.File.Snippet)
case checker.DangerousWorkflowScriptInjection:
text = fmt.Sprintf("script injection with untrusted input '%v'", e.File.Snippet)
default:
err := sce.WithMessage(sce.ErrScorecardInternal, "invalid type")
return checker.CreateRuntimeErrorResult(name, err)
}

// Untrusted checkouts.
for _, e := range r.UntrustedCheckouts {
dl.Warn(&checker.LogMessage{
Path: e.File.Path,
Type: e.File.Type,
Offset: e.File.Offset,
Text: fmt.Sprintf("untrusted code checkout '%v'", e.File.Snippet),
Text: text,
Snippet: e.File.Snippet,
})
}

if len(r.ScriptInjections) > 0 ||
len(r.UntrustedCheckouts) > 0 {
if len(r.Workflows) > 0 {
return createResult(name, checker.MinResultScore)
}
return createResult(name, checker.MaxResultScore)
Expand Down
14 changes: 8 additions & 6 deletions checks/raw/dangerous_workflow.go
Expand Up @@ -191,15 +191,16 @@ func checkJobForUntrustedCodeCheckout(job *actionlint.Job, path string,
if strings.Contains(ref.Value.Value, checkoutUntrustedPullRequestRef) ||
strings.Contains(ref.Value.Value, checkoutUntrustedWorkflowRunRef) {
line := fileparser.GetLineNumber(step.Pos)
pdata.UntrustedCheckouts = append(pdata.UntrustedCheckouts,
checker.UntrustedCheckout{
pdata.Workflows = append(pdata.Workflows,
checker.Workflow{
File: checker.File{
Path: path,
Type: checker.FileTypeSource,
Offset: line,
Snippet: ref.Value.Value,
},
Job: createJob(job),
Job: createJob(job),
Type: checker.DangerousWorkflowUntrustedCheckout,
},
)
}
Expand Down Expand Up @@ -250,15 +251,16 @@ func checkVariablesInScript(script string, pos *actionlint.Pos,
variable := script[s+3 : s+e]
if containsUntrustedContextPattern(variable) {
line := fileparser.GetLineNumber(pos)
pdata.ScriptInjections = append(pdata.ScriptInjections,
checker.ScriptInjection{
pdata.Workflows = append(pdata.Workflows,
checker.Workflow{
File: checker.File{
Path: path,
Type: checker.FileTypeSource,
Offset: line,
Snippet: variable,
},
Job: createJob(job),
Job: createJob(job),
Type: checker.DangerousWorkflowScriptInjection,
},
)
}
Expand Down
57 changes: 25 additions & 32 deletions pkg/json_raw_results.go
Expand Up @@ -16,6 +16,7 @@ package pkg

import (
"encoding/json"
"errors"
"fmt"
"io"
"time"
Expand All @@ -24,6 +25,8 @@ import (
sce "github.com/ossf/scorecard/v4/errors"
)

var errorInvalidType = errors.New("invalid type")

// Flat JSON structure to hold raw results.
type jsonScorecardRawResult struct {
Date string `json:"date"`
Expand Down Expand Up @@ -143,18 +146,20 @@ type jsonLicense struct {
}

type jsonWorkflows struct {
UntrustedCheckouts []jsonUntrustedCheckout `json:"untrustedCheckouts"`
ScriptInjections []jsonScriptInjection `json:"scriptInjections"`
DangerousPatterns []jsonDangerousPattern `json:"dangerousPatterns"`
}

type jsonUntrustedCheckout struct {
Job *jsonWorkflowJob `json:"job"`
File jsonFile `json:"file"`
}
type dangerousPatternType string

type jsonScriptInjection struct {
Job *jsonWorkflowJob `json:"job"`
File jsonFile `json:"file"`
const (
patternUntrustedCheckout dangerousPatternType = "untrustedCheckout"
patternScriptInjection dangerousPatternType = "scriptInjection"
)

type jsonDangerousPattern struct {
Job *jsonWorkflowJob `json:"job"`
File jsonFile `json:"file"`
Type dangerousPatternType `json:"type"`
}

type jsonWorkflowJob struct {
Expand Down Expand Up @@ -192,12 +197,10 @@ type jsonRawResults struct {
Releases []jsonRelease `json:"releases"`
}

//nolint:unparam
func (r *jsonScorecardRawResult) addDangerousWorkflowRawResults(df *checker.DangerousWorkflowData) error {
r.Results.Workflows = jsonWorkflows{}
// Untrusted checkouts.
for _, e := range df.UntrustedCheckouts {
v := jsonUntrustedCheckout{
for _, e := range df.Workflows {
v := jsonDangerousPattern{
File: jsonFile{
Path: e.File.Path,
Offset: int(e.File.Offset),
Expand All @@ -212,27 +215,17 @@ func (r *jsonScorecardRawResult) addDangerousWorkflowRawResults(df *checker.Dang
ID: e.Job.ID,
}
}
r.Results.Workflows.UntrustedCheckouts = append(r.Results.Workflows.UntrustedCheckouts, v)
}

// Script injections
for _, e := range df.ScriptInjections {
v := jsonScriptInjection{
File: jsonFile{
Path: e.File.Path,
Offset: int(e.File.Offset),
},
switch e.Type {
case checker.DangerousWorkflowUntrustedCheckout:
v.Type = patternUntrustedCheckout
case checker.DangerousWorkflowScriptInjection:
v.Type = patternScriptInjection
default:
return fmt.Errorf("%w: %d", errorInvalidType, e.Type)
}
if e.File.Snippet != "" {
v.File.Snippet = &e.File.Snippet
}
if e.Job != nil {
v.Job = &jsonWorkflowJob{
Name: e.Job.Name,
ID: e.Job.ID,
}
}
r.Results.Workflows.ScriptInjections = append(r.Results.Workflows.ScriptInjections, v)

r.Results.Workflows.DangerousPatterns = append(r.Results.Workflows.DangerousPatterns, v)
}

return nil
Expand Down

0 comments on commit f2241ba

Please sign in to comment.