Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Give low importance to github-owned actions #906

Merged
merged 1 commit into from
Sep 9, 2021

Conversation

nanikjava
Copy link
Contributor

@nanikjava nanikjava commented Aug 25, 2021

#802

  • Please check if the PR fulfills these requirements
  • What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)

feature update

@nanikjava nanikjava changed the title wip: fix for #802 [WIP]: fix for #802 Aug 25, 2021
@laurentsimon laurentsimon changed the title [WIP]: fix for #802 [WIP]: Give low importance to github-owned actions Aug 25, 2021
for jobName, job := range workflow.Jobs {
if len(job.Name) > 0 {
jobName = job.Name
}
for _, step := range job.Steps {
if len(step.Uses) > 0 {
// check whether we have github related action
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: start comments with capital letter and ends with full dot.

for jobName, job := range workflow.Jobs {
if len(job.Name) > 0 {
jobName = job.Name
}
for _, step := range job.Steps {
if len(step.Uses) > 0 {
// check whether we have github related action
// either action/ or github/
ghaction := regexp.MustCompile(`(actions/)`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need a regex or can we simplify by using strings.HasPrefix()?

for jobName, job := range workflow.Jobs {
if len(job.Name) > 0 {
jobName = job.Name
}
for _, step := range job.Steps {
if len(step.Uses) > 0 {
// check whether we have github related action
// either action/ or github/
ghaction := regexp.MustCompile(`(actions/)`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create a dedicated function, maybe isGitHubOwnedAction()

@@ -534,7 +547,7 @@ func validateGitHubActionWorkflow(pathfn string, content []byte,
}
}

addPinnedResult(pdata, ret)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the dependency check is the most complicated to work with. I think what you need is the following:

  1. create new structure to store workflow pinned results, something like
type worklowPinningResult struct {
 thirdParties pinnedResult
 gitHubOwned pinnedResult
}
  1. Create a function addPinnedWorkflowResult() to use for this case (here)
  2. You'll need a dataAsWorkflowResultPointer() to replace dataAsResultPointer() for this use case (here)
  3. Update createReturnForIsGitHubActionsWorkflowPinned to calculate the score as we discussed earlier.

Let me know if this clarifies things.

Thanks again for taking the time to contribute!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @laurentsimon for the comments and pointer on what to do.

I've updated the PR based from my understanding after reading your comments. Kindly give me your feedback 👍

Copy link
Contributor

@laurentsimon laurentsimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once you've updated your code, add some unit tests to verify your code does what we expect it to do.

@@ -52,6 +51,13 @@ type gitHubActionWorkflowConfig struct {
Name string `yaml:"name"`
}

// Structure to host information about pinned github
// or third party dependencies
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: end comment with full stop.

@@ -153,6 +159,16 @@ func dataAsResultPointer(data FileCbData) *pinnedResult {
return pdata
}

func dataAsWorkflowPointer(data FileCbData) *worklowPinningResult {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitL rename to dataAsWorkflowResultPointer

func createReturnForIsGitHubActionsWorkflowPinned(r pinnedResult, dl checker.DetailLogger, err error) (int, error) {
return createReturnValues(r,
func createReturnForIsGitHubActionsWorkflowPinned(r worklowPinningResult, dl checker.DetailLogger, err error) (int, error) {
return createReturnValues(r.gitHubOwned,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need a new function to return the values. The function needs to look at both gitHubOwned and thirdParties to calculate the score.


if !CheckFileContainsCommands(content, "#") {
addPinnedResult(pdata, true)
addPinnedResult(&pdata.gitHubOwned, true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need a new function addWorkflowPinnedResult that takes * worklowPinningResult as input. You can access and set gitHubOwned and thirdParties accordingly inside that function.

mgithub := ghgithub.Match([]byte(step.Uses))


if (!maction) && (!mgithub) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is where you should call addWorkflowPinnedResult to set gitHubOwned and/or thirdParties

@nanikjava
Copy link
Contributor Author

nanikjava commented Aug 27, 2021

Thank you @laurentsimon

I've updated the code based on your feedback but I'm still uncertain about the following:

  • If in the workflow file there is following uses
uses: actions/checkout@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba
uses: github/codeql-action/init@v2

does this mean that the gitHubOwned will have value pinned because one of the uses has a full hash ?

  • If in the workflow file there is following uses
uses: no-github/checkout@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba
uses: no-github/codeql-action/init@v2

does this mean that the thirdParties will have value pinned because one of the uses has a full hash ?

  • Added a separate function to do the calculation but unsure if this is the correct way to calculate ? can you please let me know.

Apology for going back and forth as I'm still trying to nail the logic down and understand it properly.

Once I get the logic correct will add more test cases and fix any broken fix test cases.

Copy link
Contributor

@laurentsimon laurentsimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're in the right direction. Add the unit tests and I'll review everything.
Note: I'm OOO from 01-Sept to 07-Sept so expect some delays for me to LGTM the PR.
Sorry about that!

return checker.InconclusiveResultScore, err
}

score := 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize to checker.MinResultScore instead of 0

switch r.gitHubOwned {
case pinned:
score += 2
case notPinned:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this case not needed since checker.MinResultScore is 0. I think we can simplify the switch and use a single if as:

if r.gitHubOwned != notPinned {
   score += 2
}

his will also take care of the case when r.gitHubOwned is pinnedUndefined which means we found no GitHub-owned actions in the workflow.

score += checker.MinResultScore
}

switch r.thirdParties {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above.

maction := strings.HasPrefix(step.Uses, "actions/")
mgithub := strings.HasPrefix(step.Uses, "github/")

if (match) && ((maction) || (mgithub)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simplify addWorkflowPinnedResult by adding 1 additionalbool: isGitHub. The function can then internally call addPinnedResult(). Something like:

githubOwned := isGitHubOwnedAction(step.Uses)
addWorkflowPinnedResult(pdata, match, githubOwned)
func addWorkflowPinnedResult(r * worklowPinningResult, to, isGitHub bool) {
  if isGitHub {
   addPinnedResult(&r.gitHubOwned, to) 
 } else {
  addPinnedResult(&r.thirdParties, to) 
}

return true, nil
}

func addWorkflowPinnedResult(w *pinnedResult, to bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment above to simplify

@nanikjava nanikjava changed the title [WIP]: Give low importance to github-owned actions Give low importance to github-owned actions Aug 31, 2021
@nanikjava nanikjava changed the title Give low importance to github-owned actions ✨ Give low importance to github-owned actions Aug 31, 2021
@nanikjava nanikjava force-pushed the f-fix-802 branch 2 times, most recently from 35fe3bc to 552949c Compare August 31, 2021 12:30
@nanikjava
Copy link
Contributor Author

nanikjava commented Aug 31, 2021

@laurentsimon PR has been modified per your suggestion and test has been added. Thank you.

Copy link
Contributor

@laurentsimon laurentsimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the hard work, this is great!
I think the next PR will be perfect and we can merge. I'm OOO until 07 Sept so expect some delay for my last LGTM. Sorry about that.

score += 8
}

if r.gitHubOwned == pinned {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the Info() inside the if r.gitHubOwned != notPinned.
Also add a call to Info() inside the if r.thirdParties != notPinned.

Use a different message for the call to Call(), and use Info3() as in https://github.com/ossf/scorecard/blob/main/checks/permissions.go#L66. Say

Info3(&checker.LogMessage{
	Path: PATH2FILE, Type: checker.FileTypeSource, Offset: LINE_NO, Snippet: SNIPPET,
	Text: fmt.Sprintf("%s %s"), "GitHub-owned", infoMsg,
	})
Info3(&checker.LogMessage{
	Path: PATH2FILE, Type: checker.FileTypeSource, Offset: LINE_NO, Snippet: SNIPPET,
	Text: fmt.Sprintf("%s %s"), "Third-party", infoMsg,
	})

If you're not sure how to get the line numbers and snippet, omit them and just add a //TODO: set Snippet and line numbers.

Last point: call createReturnValuesForGitHubActionsWorkflowPinned() with a generic message "actions are pinned"

return createReturnValues(r,
func createReturnForIsGitHubActionsWorkflowPinned(r worklowPinningResult, dl checker.DetailLogger,
err error) (int, error) {
return createReturnValuesForGitHubActionsWorkflowPinned(r,
"GitHub actions are pinned",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update this message as I said in comment above.

@@ -0,0 +1,48 @@
# Copyright 2021 Security Scorecard Authors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this file be renamed to workflow-github-pinned.yaml since it only contains pinned GitHub-owned actions?

@@ -0,0 +1,48 @@
# Copyright 2021 Security Scorecard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add additional unit tests:

  1. mix of pinned and non-pinned GitHub actions. score should be 8
  2. mixed of pinned and non-pinned non-GitHub dependencies. score should be 2
  3. mixed of the above. score should be 0
  4. all github and 3p actions pinned. score should be 10. For this one, you can simply update an existing workflow instead of creating a new file. Or you can create a new file: up to you.

@laurentsimon
Copy link
Contributor

@inferno-chromium please LGTM and merge this PR once the changes above have been made. Otherwise it will have to wait until I'm back from OOO on 08 Sept.

@nanikjava nanikjava force-pushed the f-fix-802 branch 2 times, most recently from 63b9117 to d007f73 Compare September 5, 2021 07:47
@nanikjava
Copy link
Contributor Author

@inferno-chromium please LGTM and merge this PR once the changes above have been made. Otherwise it will have to wait until I'm back from OOO on 08 Sept.

@inferno-chromium PR has been updated based on @laurentsimon feedback. Thanks.

The build/license boilerplate check (pull_request) failed due to some issue with protoc, don't have permission to re-run it.

Copy link
Contributor

@laurentsimon laurentsimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I Left a single comment in the unit test. Just address it and update your branch.
I'll check what''s wrong with the protobuf issue.

checks/pinned_dependencies_test.go Outdated Show resolved Hide resolved
@laurentsimon
Copy link
Contributor

the protobuf problem in the check may be due to your branch being out-of-date. The problem was solved recently and hopefully will go away when you update your fork.

* Different calculation between github and non-github actions

* Add test case for different kind of github and non-github action

* Modify existing test as score calculation has changed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Give low importance to github-owned actions
3 participants