Skip to content

Commit 2ea140a

Browse files
✨ Structured results for permissions (#2584)
* update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * Update checks/evaluation/permissions/GitHubWorkflowPermissionsTopNoWrite.yml Co-authored-by: Joyce <[email protected]> Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * Update checks/evaluation/permissions/GitHubWorkflowPermissionsStepsNoWrite.yml Co-authored-by: Joyce <[email protected]> Signed-off-by: laurentsimon <[email protected]> * Update checks/evaluation/permissions/GitHubWorkflowPermissionsStepsNoWrite.yml Co-authored-by: Joyce <[email protected]> Signed-off-by: laurentsimon <[email protected]> * Update checks/evaluation/permissions/GitHubWorkflowPermissionsStepsNoWrite.yml Co-authored-by: Joyce <[email protected]> Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> * update Signed-off-by: laurentsimon <[email protected]> --------- Signed-off-by: laurentsimon <[email protected]> Signed-off-by: laurentsimon <[email protected]> Co-authored-by: Joyce <[email protected]>
1 parent 4ebe521 commit 2ea140a

55 files changed

Lines changed: 1563 additions & 330 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

attestor/policy/attestation_policy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/ossf/scorecard/v4/checker"
2626
"github.com/ossf/scorecard/v4/checks"
2727
sce "github.com/ossf/scorecard/v4/errors"
28+
"github.com/ossf/scorecard/v4/finding"
2829
sclog "github.com/ossf/scorecard/v4/log"
2930
)
3031

@@ -170,7 +171,7 @@ func CheckPreventBinaryArtifacts(
170171
logger.Info(
171172
fmt.Sprintf(
172173
"binary detected path:%s type: %v offset:%v",
173-
artifactFile.Path, checker.FileTypeBinary, artifactFile.Offset,
174+
artifactFile.Path, finding.FileTypeBinary, artifactFile.Offset,
174175
),
175176
)
176177
return Fail, nil

checker/check_result.go

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ package checker
1818
import (
1919
"fmt"
2020
"math"
21+
22+
"github.com/ossf/scorecard/v4/finding"
23+
"github.com/ossf/scorecard/v4/rule"
2124
)
2225

2326
type (
2427
// DetailType is the type of details.
2528
DetailType int
26-
// FileType is the type of a file.
27-
FileType int
2829
)
2930

3031
const (
@@ -49,42 +50,18 @@ const (
4950
DetailDebug
5051
)
5152

52-
const (
53-
// FileTypeNone is a default, not defined.
54-
// FileTypeNone must be `0`.
55-
FileTypeNone FileType = iota
56-
// FileTypeSource is for source code files.
57-
FileTypeSource
58-
// FileTypeBinary is for binary files.
59-
FileTypeBinary
60-
// FileTypeText is for text files.
61-
FileTypeText
62-
// FileTypeURL for URLs.
63-
FileTypeURL
64-
)
65-
6653
// CheckResult captures result from a check run.
6754
//
6855
//nolint:govet
6956
type CheckResult struct {
7057
Name string
7158
Version int
7259
Error error
73-
Details []CheckDetail
7460
Score int
7561
Reason string
76-
}
77-
78-
// Remediation represents a remediation.
79-
type Remediation struct {
80-
// Code snippet for humans.
81-
Snippet string
82-
// Diff for machines.
83-
Diff string
84-
// Help text for humans.
85-
HelpText string
86-
// Help text in markdown format for humans.
87-
HelpMarkdown string
62+
Details []CheckDetail
63+
// Structured results.
64+
Rules []string // TODO(X): add support.
8865
}
8966

9067
// CheckDetail contains information for each detail.
@@ -98,13 +75,17 @@ type CheckDetail struct {
9875
//
9976
//nolint:govet
10077
type LogMessage struct {
101-
Text string // A short string explaining why the detail was recorded/logged.
102-
Path string // Fullpath to the file.
103-
Type FileType // Type of file.
104-
Offset uint // Offset in the file of Path (line for source/text files).
105-
EndOffset uint // End of offset in the file, e.g. if the command spans multiple lines.
106-
Snippet string // Snippet of code
107-
Remediation *Remediation // Remediation information, if any.
78+
// Structured resuts.
79+
Finding *finding.Finding
80+
81+
// Non-structured results.
82+
Text string // A short string explaining why the detail was recorded/logged.
83+
Path string // Fullpath to the file.
84+
Type finding.FileType // Type of file.
85+
Offset uint // Offset in the file of Path (line for source/text files).
86+
EndOffset uint // End of offset in the file, e.g. if the command spans multiple lines.
87+
Snippet string // Snippet of code
88+
Remediation *rule.Remediation // Remediation information, if any.
10889
}
10990

11091
// CreateProportionalScore creates a proportional score.

checker/raw_result.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"time"
1919

2020
"github.com/ossf/scorecard/v4/clients"
21+
"github.com/ossf/scorecard/v4/finding"
2122
)
2223

2324
// RawResults contains results before a policy
@@ -286,11 +287,11 @@ type ArchivedStatus struct {
286287
// File represents a file.
287288
type File struct {
288289
Path string
289-
Snippet string // Snippet of code
290-
Offset uint // Offset in the file of Path (line for source/text files).
291-
EndOffset uint // End of offset in the file, e.g. if the command spans multiple lines.
292-
FileSize uint // Total size of file.
293-
Type FileType // Type of file.
290+
Snippet string // Snippet of code
291+
Offset uint // Offset in the file of Path (line for source/text files).
292+
EndOffset uint // End of offset in the file, e.g. if the command spans multiple lines.
293+
FileSize uint // Total size of file.
294+
Type finding.FileType // Type of file.
294295
// TODO: add hash.
295296
}
296297

checks/evaluation/binary_artifacts.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package evaluation
1717
import (
1818
"github.com/ossf/scorecard/v4/checker"
1919
sce "github.com/ossf/scorecard/v4/errors"
20+
"github.com/ossf/scorecard/v4/finding"
2021
)
2122

2223
// BinaryArtifacts applies the score policy for the Binary-Artifacts check.
@@ -36,7 +37,7 @@ func BinaryArtifacts(name string, dl checker.DetailLogger,
3637
score := checker.MaxResultScore
3738
for _, f := range r.Files {
3839
dl.Warn(&checker.LogMessage{
39-
Path: f.Path, Type: checker.FileTypeBinary,
40+
Path: f.Path, Type: finding.FileTypeBinary,
4041
Offset: f.Offset,
4142
Text: "binary detected",
4243
})

checks/evaluation/ci_tests.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"strings"
2020

2121
"github.com/ossf/scorecard/v4/checker"
22+
"github.com/ossf/scorecard/v4/finding"
2223
)
2324

2425
const (
@@ -85,7 +86,7 @@ func prHasSuccessStatus(r checker.RevisionCIInfo, dl checker.DetailLogger) (bool
8586
if isTest(status.Context) || isTest(status.TargetURL) {
8687
dl.Debug(&checker.LogMessage{
8788
Path: status.URL,
88-
Type: checker.FileTypeURL,
89+
Type: finding.FileTypeURL,
8990
Text: fmt.Sprintf("CI test found: pr: %s, context: %s", r.HeadSHA,
9091
status.Context),
9192
})
@@ -109,7 +110,7 @@ func prHasSuccessfulCheck(r checker.RevisionCIInfo, dl checker.DetailLogger) (bo
109110
if isTest(cr.App.Slug) {
110111
dl.Debug(&checker.LogMessage{
111112
Path: cr.URL,
112-
Type: checker.FileTypeURL,
113+
Type: finding.FileTypeURL,
113114
Text: fmt.Sprintf("CI test found: pr: %d, context: %s", r.PullRequestNumber,
114115
cr.App.Slug),
115116
})

checks/evaluation/dependency_update_tool_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/ossf/scorecard/v4/checker"
2121
sce "github.com/ossf/scorecard/v4/errors"
22+
"github.com/ossf/scorecard/v4/finding"
2223
scut "github.com/ossf/scorecard/v4/utests"
2324
)
2425

@@ -95,7 +96,7 @@ func TestDependencyUpdateTool(t *testing.T) {
9596
[dependency-update-tool]
9697
enabled = true
9798
`,
98-
Type: checker.FileTypeSource,
99+
Type: finding.FileTypeSource,
99100
},
100101
},
101102
},

checks/evaluation/license.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package evaluation
1717
import (
1818
"github.com/ossf/scorecard/v4/checker"
1919
sce "github.com/ossf/scorecard/v4/errors"
20+
"github.com/ossf/scorecard/v4/finding"
2021
)
2122

2223
func scoreLicenseCriteria(f *checker.LicenseFile,
@@ -25,12 +26,12 @@ func scoreLicenseCriteria(f *checker.LicenseFile,
2526
var score int
2627
msg := checker.LogMessage{
2728
Path: "",
28-
Type: checker.FileTypeNone,
29+
Type: finding.FileTypeNone,
2930
Text: "",
3031
Offset: 1,
3132
}
3233
msg.Path = f.File.Path
33-
msg.Type = checker.FileTypeSource
34+
msg.Type = finding.FileTypeSource
3435
// #1 a license file was found.
3536
score += 6
3637

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2023 OpenSSF Scorecard Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
short: Checks that GitHub workflows do not have steps with dangerous write permissions
16+
desc: This rule checks that GitHub workflows do not have steps with dangerous write permissions
17+
motivation: >
18+
Even with permissions default set to read, some scopes having write permissions in their steps brings incurs a risk to the project.
19+
By giving write permission to the Actions you call in jobs, an external Action you call could abuse them. Depending on the permissions,
20+
this could let the external Action commit unreviewed code, remove pre-submit checks to introduce a bug.
21+
For more information about the scopes and the vulnerabilities involved, see https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions.
22+
23+
implementation: >
24+
The rule is implemented by checking whether the `permissions` keyword is given non-write permissions for the following
25+
scopes: `statuses`, `checks`, `security-events`, `deployments`, `contents`, `packages`, `actions`.
26+
Write permissions given to recognized packaging actions or commands are allowed and are considered an acceptable risk.
27+
risk: Medium
28+
remediation:
29+
effort: High
30+
text:
31+
- Verify which permissions are needed and consider whether you can reduce them.
32+
markdown:
33+
- Verify which permissions are needed and consider whether you can reduce them.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright 2023 OpenSSF Scorecard Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
short: Checks that GitHub workflows do not have default write permissions
16+
desc: This rule checks that GitHub workflows do not have default write permissions
17+
motivation: >
18+
If no permissions are declared, a workflow's GitHub token's permissions default to write for all scopes.
19+
This include write permissions to push to the repository, to read encrypted secrets, etc.
20+
For more information, see https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token.
21+
implementation: >
22+
The rule is implemented by checking whether the `permissions` keyword is defined at the top of the workflow,
23+
and that no write permissions are given.
24+
risk: High
25+
remediation:
26+
effort: Low
27+
text:
28+
- Visit https://app.stepsecurity.io/secureworkflow/${{ repo }}/${{ workflow }}/${{ branch }}?enable=permissions
29+
- Tick the 'Restrict permissions for GITHUB_TOKEN'
30+
- Untick other options
31+
- "NOTE: If you want to resolve multiple issues at once, you can visit https://app.stepsecurity.io/securerepo instead."
32+
markdown:
33+
- Visit [https://app.stepsecurity.io/secureworkflow](https://app.stepsecurity.io/secureworkflow/${{ repo }}/${{ workflow }}/${{ branch }}?enable=permissions).
34+
- Tick the 'Restrict permissions for GITHUB_TOKEN'
35+
- Untick other options
36+
- "NOTE: If you want to resolve multiple issues at once, you can visit [https://app.stepsecurity.io/securerepo](https://app.stepsecurity.io/securerepo) instead."

0 commit comments

Comments
 (0)