/
codeql.go
129 lines (107 loc) · 3.33 KB
/
codeql.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package codeql
import (
"context"
piperGithub "github.com/SAP/jenkins-library/pkg/github"
"github.com/google/go-github/v45/github"
)
type CodeqlScanAudit interface {
GetVulnerabilities(analyzedRef string, state string) error
}
type githubCodeqlScanningService interface {
ListAlertsForRepo(ctx context.Context, owner, repo string, opts *github.AlertListOptions) ([]*github.Alert, *github.Response, error)
}
const auditStateOpen string = "open"
const auditStateDismissed string = "dismissed"
const codeqlToolName string = "CodeQL"
const perPageCount int = 100
const AuditAll string = "Audit All"
const Optional string = "Optional"
func NewCodeqlScanAuditInstance(serverUrl, owner, repository, token string, trustedCerts []string) CodeqlScanAuditInstance {
return CodeqlScanAuditInstance{serverUrl: serverUrl, owner: owner, repository: repository, token: token, trustedCerts: trustedCerts}
}
type CodeqlScanAuditInstance struct {
serverUrl string
owner string
repository string
token string
trustedCerts []string
alertListoptions github.AlertListOptions
}
func (codeqlScanAudit *CodeqlScanAuditInstance) GetVulnerabilities(analyzedRef string) ([]CodeqlFindings, error) {
apiUrl := getApiUrl(codeqlScanAudit.serverUrl)
ctx, client, err := piperGithub.
NewClientBuilder(codeqlScanAudit.token, apiUrl).
WithTrustedCerts(codeqlScanAudit.trustedCerts).Build()
if err != nil {
return []CodeqlFindings{}, err
}
return getVulnerabilitiesFromClient(ctx, client.CodeScanning, analyzedRef, codeqlScanAudit)
}
func getVulnerabilitiesFromClient(ctx context.Context, codeScanning githubCodeqlScanningService, analyzedRef string, codeqlScanAudit *CodeqlScanAuditInstance) ([]CodeqlFindings, error) {
page := 1
audited := 0
totalAlerts := 0
optionalAudited := 0
totalOptionalAlerts := 0
for page != 0 {
alertOptions := github.AlertListOptions{
State: "",
Ref: analyzedRef,
ListOptions: github.ListOptions{
Page: page,
PerPage: perPageCount,
},
}
alerts, response, err := codeScanning.ListAlertsForRepo(ctx, codeqlScanAudit.owner, codeqlScanAudit.repository, &alertOptions)
if err != nil {
return []CodeqlFindings{}, err
}
page = response.NextPage
for _, alert := range alerts {
if *alert.Tool.Name != codeqlToolName {
continue
}
isSecurityIssue := false
for _, tag := range alert.Rule.Tags {
if tag == "security" {
isSecurityIssue = true
}
}
if isSecurityIssue {
if *alert.State == auditStateDismissed {
audited += 1
totalAlerts += 1
}
if *alert.State == auditStateOpen {
totalAlerts += 1
}
} else {
if *alert.State == auditStateDismissed {
optionalAudited += 1
totalOptionalAlerts += 1
}
if *alert.State == auditStateOpen {
totalOptionalAlerts += 1
}
}
}
}
auditAll := CodeqlFindings{
ClassificationName: AuditAll,
Total: totalAlerts,
Audited: audited,
}
optionalIssues := CodeqlFindings{
ClassificationName: Optional,
Total: totalOptionalAlerts,
Audited: optionalAudited,
}
codeqlScanning := []CodeqlFindings{auditAll, optionalIssues}
return codeqlScanning, nil
}
func getApiUrl(serverUrl string) string {
if serverUrl == "https://github.com" {
return "https://api.github.com"
}
return (serverUrl + "/api/v3")
}