@@ -82,7 +82,7 @@ func verifyGitHubFrogbotEnvironment(client vcsclient.VcsClient, repoConfig *util
82
82
// a. Audit the dependencies of the source and the target branches.
83
83
// b. Compare the vulnerabilities found in source and target branches, and show only the new vulnerabilities added by the pull request.
84
84
// Otherwise, only the source branch is scanned and all found vulnerabilities are being displayed.
85
- func scanPullRequest (repo * utils.Repository , client vcsclient.VcsClient ) error {
85
+ func scanPullRequest (repo * utils.Repository , client vcsclient.VcsClient ) ( err error ) {
86
86
pullRequestDetails := repo .PullRequestDetails
87
87
log .Info (fmt .Sprintf ("Scanning Pull Request #%d (from source branch: <%s/%s/%s> to target branch: <%s/%s/%s>)" ,
88
88
pullRequestDetails .ID ,
@@ -91,33 +91,47 @@ func scanPullRequest(repo *utils.Repository, client vcsclient.VcsClient) error {
91
91
log .Info ("-----------------------------------------------------------" )
92
92
93
93
// Audit PR code
94
- vulnerabilitiesRows , iacRows , err := auditPullRequest (repo , client , pullRequestDetails )
94
+ vulnerabilitiesRows , iacRows , secretsRows , err := auditPullRequest (repo , client , pullRequestDetails )
95
95
if err != nil {
96
- return err
96
+ return
97
+ }
98
+
99
+ shouldSendExposedSecretsEmail := len (secretsRows ) > 0 && repo .SmtpServer != ""
100
+ if shouldSendExposedSecretsEmail {
101
+ prSourceDetails := pullRequestDetails .Source
102
+ secretsEmailDetails := utils .NewSecretsEmailDetails (
103
+ client , repo .GitProvider ,
104
+ prSourceDetails .Owner , prSourceDetails .Repository ,
105
+ prSourceDetails .Name , pullRequestDetails .URL ,
106
+ secretsRows , repo .EmailDetails )
107
+ if err = utils .AlertSecretsExposed (secretsEmailDetails ); err != nil {
108
+ return
109
+ }
97
110
}
98
111
99
112
// Delete previous Frogbot pull request message if exists
100
113
if err = deleteExistingPullRequestComment (repo , client ); err != nil {
101
- return err
114
+ return
102
115
}
103
116
104
117
// Create a pull request message
105
118
message := createPullRequestMessage (vulnerabilitiesRows , iacRows , repo .OutputWriter )
106
119
107
120
// Add comment to the pull request
108
121
if err = client .AddPullRequestComment (context .Background (), repo .RepoOwner , repo .RepoName , message , int (pullRequestDetails .ID )); err != nil {
109
- return errors .New ("couldn't add pull request comment: " + err .Error ())
122
+ err = errors .New ("couldn't add pull request comment: " + err .Error ())
123
+ return
110
124
}
111
125
112
126
// Fail the Frogbot task if a security issue is found and Frogbot isn't configured to avoid the failure.
113
127
if repo .FailOnSecurityIssues != nil && * repo .FailOnSecurityIssues && len (vulnerabilitiesRows ) > 0 {
114
128
err = errors .New (securityIssueFoundErr )
115
129
}
116
- return err
130
+ return
117
131
}
118
132
119
133
// Downloads Pull Requests branches code and audits them
120
- func auditPullRequest (repoConfig * utils.Repository , client vcsclient.VcsClient , pullRequestDetails vcsclient.PullRequestInfo ) (vulnerabilitiesRows []formats.VulnerabilityOrViolationRow , iacRows []formats.IacSecretsRow , err error ) {
134
+ func auditPullRequest (repoConfig * utils.Repository , client vcsclient.VcsClient , pullRequestDetails vcsclient.PullRequestInfo ) (vulnerabilitiesRows []formats.VulnerabilityOrViolationRow , iacRows []formats.IacSecretsRow , secretsRows []formats. IacSecretsRow , err error ) {
121
135
// Download source branch
122
136
sourceBranchInfo := pullRequestDetails .Source
123
137
sourceBranchWd , cleanupSource , err := utils .DownloadRepoToTempDir (client , sourceBranchInfo .Owner , sourceBranchInfo .Repository , sourceBranchInfo .Name )
@@ -157,8 +171,8 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient,
157
171
}
158
172
159
173
// Set JAS output flags
160
- extendedScanResults := sourceResults .ExtendedScanResults
161
- repoConfig .OutputWriter .SetJasOutputFlags (extendedScanResults .EntitledForJas , len (extendedScanResults .ApplicabilityScanResults ) > 0 )
174
+ sourceScanResults := sourceResults .ExtendedScanResults
175
+ repoConfig .OutputWriter .SetJasOutputFlags (sourceScanResults .EntitledForJas , len (sourceScanResults .ApplicabilityScanResults ) > 0 )
162
176
163
177
// Get all issues that were found in the source branch
164
178
if repoConfig .IncludeAllVulnerabilities {
@@ -169,7 +183,8 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient,
169
183
return
170
184
}
171
185
vulnerabilitiesRows = append (vulnerabilitiesRows , allIssuesRows ... )
172
- iacRows = append (iacRows , xrayutils .PrepareIacs (sourceResults .ExtendedScanResults .IacScanResults )... )
186
+ iacRows = append (iacRows , xrayutils .PrepareIacs (sourceScanResults .IacScanResults )... )
187
+ secretsRows = append (secretsRows , xrayutils .PrepareSecrets (sourceScanResults .SecretsScanResults )... )
173
188
continue
174
189
}
175
190
@@ -180,35 +195,62 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient,
180
195
if err != nil {
181
196
return
182
197
}
183
- var newIssuesRows []formats.VulnerabilityOrViolationRow
184
- newIssuesRows , err = createNewIssuesRows (targetResults , sourceResults )
185
- if err != nil {
198
+
199
+ // Get new issues
200
+ var newVulnerabilities []formats.VulnerabilityOrViolationRow
201
+ var newIacs , newSecrets []formats.IacSecretsRow
202
+ if newVulnerabilities , newIacs , newSecrets , err = getNewIssues (targetResults , sourceResults ); err != nil {
186
203
return
187
204
}
188
- vulnerabilitiesRows = append (vulnerabilitiesRows , newIssuesRows ... )
189
- iacRows = append (iacRows , createNewIacRows (targetResults .ExtendedScanResults .IacScanResults , sourceResults .ExtendedScanResults .IacScanResults )... )
205
+ vulnerabilitiesRows = append (vulnerabilitiesRows , newVulnerabilities ... )
206
+ iacRows = append (iacRows , newIacs ... )
207
+ secretsRows = append (secretsRows , newSecrets ... )
190
208
}
191
209
return
192
210
}
193
211
194
- func createNewIacRows (targetIacResults , sourceIacResults []xrayutils.IacOrSecretResult ) []formats.IacSecretsRow {
195
- targetIacRows := xrayutils .PrepareIacs (targetIacResults )
196
- sourceIacRows := xrayutils .PrepareIacs (sourceIacResults )
197
- targetIacVulnerabilitiesKeys := datastructures .MakeSet [string ]()
198
- for _ , row := range targetIacRows {
199
- targetIacVulnerabilitiesKeys .Add (row .File + row .Text )
200
- }
201
- var addedIacVulnerabilities []formats.IacSecretsRow
202
- for _ , row := range sourceIacRows {
203
- if ! targetIacVulnerabilitiesKeys .Exists (row .File + row .Text ) {
204
- addedIacVulnerabilities = append (addedIacVulnerabilities , row )
212
+ func getNewIssues (targetResults , sourceResults * audit.Results ) ([]formats.VulnerabilityOrViolationRow , []formats.IacSecretsRow , []formats.IacSecretsRow , error ) {
213
+ var newVulnerabilities []formats.VulnerabilityOrViolationRow
214
+ var err error
215
+ if len (sourceResults .ExtendedScanResults .XrayResults ) > 0 {
216
+ if newVulnerabilities , err = createNewVulnerabilitiesRows (targetResults , sourceResults ); err != nil {
217
+ return nil , nil , nil , err
218
+ }
219
+ }
220
+
221
+ var newIacs []formats.IacSecretsRow
222
+ if len (sourceResults .ExtendedScanResults .IacScanResults ) > 0 {
223
+ targetIacRows := xrayutils .PrepareIacs (targetResults .ExtendedScanResults .IacScanResults )
224
+ sourceIacRows := xrayutils .PrepareIacs (sourceResults .ExtendedScanResults .IacScanResults )
225
+ newIacs = createNewIacOrSecretsRows (targetIacRows , sourceIacRows )
226
+ }
227
+
228
+ var newSecrets []formats.IacSecretsRow
229
+ if len (sourceResults .ExtendedScanResults .SecretsScanResults ) > 0 {
230
+ targetSecretsRows := xrayutils .PrepareSecrets (targetResults .ExtendedScanResults .SecretsScanResults )
231
+ sourceSecretsRows := xrayutils .PrepareSecrets (sourceResults .ExtendedScanResults .SecretsScanResults )
232
+ newSecrets = createNewIacOrSecretsRows (targetSecretsRows , sourceSecretsRows )
233
+ }
234
+
235
+ return newVulnerabilities , newIacs , newSecrets , nil
236
+ }
237
+
238
+ func createNewIacOrSecretsRows (targetResults , sourceResults []formats.IacSecretsRow ) []formats.IacSecretsRow {
239
+ targetIacOrSecretsVulnerabilitiesKeys := datastructures .MakeSet [string ]()
240
+ for _ , row := range targetResults {
241
+ targetIacOrSecretsVulnerabilitiesKeys .Add (row .File + row .Text )
242
+ }
243
+ var addedIacOrSecretsVulnerabilities []formats.IacSecretsRow
244
+ for _ , row := range sourceResults {
245
+ if ! targetIacOrSecretsVulnerabilitiesKeys .Exists (row .File + row .Text ) {
246
+ addedIacOrSecretsVulnerabilities = append (addedIacOrSecretsVulnerabilities , row )
205
247
}
206
248
}
207
- return addedIacVulnerabilities
249
+ return addedIacOrSecretsVulnerabilities
208
250
}
209
251
210
252
// Create vulnerabilities rows. The rows should contain only the new issues added by this PR
211
- func createNewIssuesRows (targetResults , sourceResults * audit.Results ) (vulnerabilitiesRows []formats.VulnerabilityOrViolationRow , err error ) {
253
+ func createNewVulnerabilitiesRows (targetResults , sourceResults * audit.Results ) (vulnerabilitiesRows []formats.VulnerabilityOrViolationRow , err error ) {
212
254
targetScanAggregatedResults := aggregateScanResults (targetResults .ExtendedScanResults .XrayResults )
213
255
sourceScanAggregatedResults := aggregateScanResults (sourceResults .ExtendedScanResults .XrayResults )
214
256
@@ -305,9 +347,12 @@ func createPullRequestMessage(vulnerabilitiesRows []formats.VulnerabilityOrViola
305
347
306
348
func deleteExistingPullRequestComment (repository * utils.Repository , client vcsclient.VcsClient ) error {
307
349
log .Debug ("Looking for an existing Frogbot pull request comment. Deleting it if it exists..." )
308
- comments , err := utils .GetSortedPullRequestComments (client , repository .RepoOwner , repository .RepoName , int (repository .PullRequestDetails .ID ))
350
+ prDetails := repository .PullRequestDetails
351
+ comments , err := utils .GetSortedPullRequestComments (client , prDetails .Target .Owner , prDetails .Target .Repository , int (prDetails .ID ))
309
352
if err != nil {
310
- return err
353
+ return fmt .Errorf (
354
+ "failed to get comments. the following details were used in order to fetch the comments: <%s/%s> pull request #%d. the error received: %s" ,
355
+ repository .RepoOwner , repository .RepoName , int (repository .PullRequestDetails .ID ), err .Error ())
311
356
}
312
357
313
358
commentID := frogbotCommentNotFound
@@ -320,7 +365,7 @@ func deleteExistingPullRequestComment(repository *utils.Repository, client vcscl
320
365
}
321
366
322
367
if commentID != frogbotCommentNotFound {
323
- err = client .DeletePullRequestComment (context .Background (), repository . RepoOwner , repository . RepoName , int (repository . PullRequestDetails .ID ), commentID )
368
+ err = client .DeletePullRequestComment (context .Background (), prDetails . Target . Owner , prDetails . Target . Repository , int (prDetails .ID ), commentID )
324
369
}
325
370
326
371
return err
0 commit comments