Skip to content

Commit 2e87ab6

Browse files
authored
Secrets & Infrastructure as Code scanning (#364)
1 parent 1811910 commit 2e87ab6

Some content is hidden

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

53 files changed

+800
-270
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ jobs:
6060

6161
# Run tests
6262
- name: Tests
63-
run: go test ./... -v -race -timeout 0 -cover -coverprofile=covprofile -covermode=atomic
63+
run: go test ./... -v -race -timeout 30m -cover -coverprofile=covprofile -covermode=atomic
6464
env:
6565
JF_URL: ${{ secrets.PLATFORM_URL }}
6666
JF_ACCESS_TOKEN: ${{ secrets.PLATFORM_ADMIN_TOKEN }}
67+
JFROG_CLI_LOG_LEVEL: "DEBUG"
6768
# Generate code coverage
6869
- name: Send coverage
6970
run: |

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,21 +216,18 @@ Frogbot adds the scan results to the pull request in the following format:
216216

217217
If no new vulnerabilities are found, Frogbot automatically adds the following comment to the pull request:
218218

219-
[![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/noVulnerabilityBanner.png)](#-no-issues)
219+
[![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/noVulnerabilityBanner.png)](#-no-issues)
220220

221221
##### 👎 Issues were found
222222

223223
If new vulnerabilities are found, Frogbot adds them as a comment on the pull request. For example:
224224

225-
[![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/vulnerabilitiesBanner.png)](#-issues-were-found)
226-
227-
| SEVERITY | DIRECT<br>DEPENDENCIES | DIRECT<br>DEPENDENCIES<br>VERSIONS | IMPACTED<br>DEPENDENCY<br>NAME | IMPACTED<br>DEPENDENCY<br>VERSION | FIXED<br>VERSIONS | CVE
228-
:------------------------------------------------------------------------------------------------------:| -- | -- | -- | -- |:-----------------:| --
229-
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/criticalSeverity.png)<br>Critical | lion-webview | v0.1.20 | ten-webpack | v4.75.0 | [v4.76.0] | CVE-2023-28154
230-
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/highSeverity.png)<br>High | magic-streaming-server | v0.21.10 | ten-webpack | v4.75.0 | [v4.76.0] | CVE-2023-28154
231-
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/highSeverity.png)<br>High | jump-archiver | v3.5.1 | quicksilver | v5.75.0 | [v5.76.0] | CVE-2023-28154
232-
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/mediumSeverity.png)<br>Medium | expense-calculator | v6.6.0 | cve-alpha | v1.10.0 | [v1.10.1] | CVE-2023-28154
233-
225+
| SEVERITY | CONTEXTUAL ANALYSIS | DIRECT DEPENDENCIES | IMPACTED DEPENDENCY | FIXED VERSIONS |
226+
|:-------------------------------------------------------------------------------------------------------------------:| :----------------------------------: | :----------------------------------: | :-----------------------------------: | :---------------------------------: |
227+
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/applicableCriticalSeverity.png)<br>Critical | $\color{}{\textsf{Undetermined}}$ |vconsole:3.15.0 | vconsole:3.15.0 | |
228+
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/notApplicableCritical.png)<br>Critical | $\color{#3CB371}{\textsf{Not Applicable}}$ |minimist:1.2.5 | minimist:1.2.5 | [0.2.4]<br>[1.2.6] |
229+
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/applicableHighSeverity.png)<br> High | $\color{#FF7377}{\textsf{Applicable}}$ |protobufjs:6.11.2 | protobufjs:6.11.2 | [6.11.3] |
230+
| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/notApplicableHigh.png)<br> High | $\color{#3CB371}{\textsf{Not Applicable}}$ |lodash:4.17.19 | lodash:4.17.19 | [4.17.21] |
234231
### Scanning repositories and fixing issues
235232

236233
Frogbot scans your Git repository and automatically opens pull requests for upgrading vulnerable dependencies to a version with a fix.
@@ -243,6 +240,10 @@ For GitHub repositories, Frogbot also adds [Security Alerts](https://docs.github
243240

244241
![](./images/github-code-scanning-content.png)
245242

243+
![](./images/github-code-scanning-secrets-content.png)
244+
245+
![](./images/github-code-scanning-iac-content.png)
246+
246247
Frogbot uses [JFrog Xray](https://jfrog.com/xray/) for the scanning. The scanning is triggered following commits that are pushed to the repository.
247248

248249
Supported package management tools:

action/lib/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function main() {
4747
break;
4848
case "push":
4949
case "schedule":
50+
case "workflow_dispatch":
5051
yield utils_1.Utils.execCreateFixPullRequests();
5152
break;
5253
default:

action/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

commands/createfixpullrequests.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func (cfp *CreateFixPullRequestsCmd) openFixingPullRequest(fixBranchName string,
261261
pullRequestTitle := cfp.gitManager.GeneratePullRequestTitle(vulnDetails.ImpactedDependencyName, vulnDetails.FixVersion)
262262
log.Debug("Creating Pull Request form:", fixBranchName, " to:", cfp.details.Branch())
263263

264-
prBody := cfp.OutputWriter.Content([]formats.VulnerabilityOrViolationRow{*vulnDetails.VulnerabilityOrViolationRow})
264+
prBody := cfp.OutputWriter.VulnerabilitiesContent([]formats.VulnerabilityOrViolationRow{*vulnDetails.VulnerabilityOrViolationRow})
265265
return cfp.details.Client().CreatePullRequest(context.Background(), cfp.details.RepoOwner, cfp.details.RepoName, fixBranchName, cfp.details.Branch(), pullRequestTitle, prBody)
266266
}
267267

@@ -292,7 +292,7 @@ func (cfp *CreateFixPullRequestsCmd) openAggregatedPullRequest(fixBranchName str
292292
}
293293
if !exists {
294294
log.Info("Creating Pull Request from:", fixBranchName, "to:", cfp.details.Branch())
295-
prBody := cfp.OutputWriter.Content(vulnerabilities)
295+
prBody := cfp.OutputWriter.VulnerabiltiesTitle(false) + "\n" + cfp.OutputWriter.VulnerabilitiesContent(vulnerabilities)
296296
return cfp.details.Client().CreatePullRequest(context.Background(), cfp.details.RepoOwner, cfp.details.RepoName, fixBranchName, cfp.details.Branch(), utils.AggregatedPullRequestTitleTemplate, prBody)
297297
}
298298
log.Info("Pull Request branch:", fixBranchName, "has been updated")

commands/scanpullrequest.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"github.com/jfrog/gofrog/datastructures"
78
"os"
89
"os/exec"
910
"path/filepath"
@@ -53,13 +54,13 @@ func scanPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient) e
5354
}
5455

5556
// Audit PR code
56-
vulnerabilitiesRows, err := auditPullRequest(repoConfig, client)
57+
vulnerabilitiesRows, iacRows, err := auditPullRequest(repoConfig, client)
5758
if err != nil {
5859
return err
5960
}
6061

6162
// Create a pull request message
62-
message := createPullRequestMessage(vulnerabilitiesRows, repoConfig.OutputWriter)
63+
message := createPullRequestMessage(vulnerabilitiesRows, iacRows, repoConfig.OutputWriter)
6364

6465
// Add comment to the pull request
6566
if err = client.AddPullRequestComment(context.Background(), repoConfig.RepoOwner, repoConfig.RepoName, message, repoConfig.PullRequestID); err != nil {
@@ -73,8 +74,9 @@ func scanPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient) e
7374
return err
7475
}
7576

76-
func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient) ([]formats.VulnerabilityOrViolationRow, error) {
77+
func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient) ([]formats.VulnerabilityOrViolationRow, []formats.IacSecretsRow, error) {
7778
var vulnerabilitiesRows []formats.VulnerabilityOrViolationRow
79+
var iacRows []formats.IacSecretsRow
7880
for i := range repoConfig.Projects {
7981
scanDetails := utils.NewScanDetails(client, &repoConfig.Server, &repoConfig.Git).
8082
SetProject(&repoConfig.Projects[i]).
@@ -84,32 +86,50 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient)
8486
SetFixableOnly(repoConfig.FixableOnly)
8587
sourceResults, err := auditSource(scanDetails)
8688
if err != nil {
87-
return nil, err
89+
return nil, nil, err
8890
}
8991
repoConfig.SetEntitledForJas(sourceResults.ExtendedScanResults.EntitledForJas)
9092
if repoConfig.IncludeAllVulnerabilities {
9193
log.Info("Frogbot is configured to show all vulnerabilities")
9294
allIssuesRows, err := getScanVulnerabilitiesRows(sourceResults)
9395
if err != nil {
94-
return nil, err
96+
return nil, nil, err
9597
}
9698
vulnerabilitiesRows = append(vulnerabilitiesRows, allIssuesRows...)
99+
iacRows = append(iacRows, xrayutils.PrepareIacs(sourceResults.ExtendedScanResults.IacScanResults)...)
97100
continue
98101
}
99102
// Audit target code
100103
scanDetails.SetFailOnInstallationErrors(*repoConfig.FailOnSecurityIssues).SetBranch(repoConfig.Branches[0])
101104
targetResults, err := auditTarget(scanDetails)
102105
if err != nil {
103-
return nil, err
106+
return nil, nil, err
104107
}
105108
newIssuesRows, err := createNewIssuesRows(targetResults, sourceResults)
106109
if err != nil {
107-
return nil, err
110+
return nil, nil, err
108111
}
109112
vulnerabilitiesRows = append(vulnerabilitiesRows, newIssuesRows...)
113+
iacRows = append(iacRows, createNewIacRows(targetResults.ExtendedScanResults.IacScanResults, sourceResults.ExtendedScanResults.IacScanResults)...)
110114
}
111115
log.Info("Xray scan completed")
112-
return vulnerabilitiesRows, nil
116+
return vulnerabilitiesRows, iacRows, nil
117+
}
118+
119+
func createNewIacRows(targetIacResults, sourceIacResults []xrayutils.IacOrSecretResult) []formats.IacSecretsRow {
120+
targetIacRows := xrayutils.PrepareIacs(targetIacResults)
121+
sourceIacRows := xrayutils.PrepareIacs(sourceIacResults)
122+
targetIacVulnerabilitiesKeys := datastructures.MakeSet[string]()
123+
for _, row := range targetIacRows {
124+
targetIacVulnerabilitiesKeys.Add(row.File + row.Text)
125+
}
126+
var addedIacVulnerabilities []formats.IacSecretsRow
127+
for _, row := range sourceIacRows {
128+
if !targetIacVulnerabilitiesKeys.Exists(row.File + row.Text) {
129+
addedIacVulnerabilities = append(addedIacVulnerabilities, row)
130+
}
131+
}
132+
return addedIacVulnerabilities
113133
}
114134

115135
// Verify that the 'frogbot' GitHub environment was properly configured on the repository
@@ -339,9 +359,9 @@ func getUniqueID(vulnerability formats.VulnerabilityOrViolationRow) string {
339359
return vulnerability.ImpactedDependencyName + vulnerability.ImpactedDependencyVersion + vulnerability.IssueId
340360
}
341361

342-
func createPullRequestMessage(vulnerabilitiesRows []formats.VulnerabilityOrViolationRow, writer utils.OutputWriter) string {
343-
if len(vulnerabilitiesRows) == 0 {
362+
func createPullRequestMessage(vulnerabilitiesRows []formats.VulnerabilityOrViolationRow, iacRows []formats.IacSecretsRow, writer utils.OutputWriter) string {
363+
if len(vulnerabilitiesRows) == 0 && len(iacRows) == 0 {
344364
return writer.NoVulnerabilitiesTitle() + utils.JasMsg(writer.EntitledForJas()) + writer.Footer()
345365
}
346-
return writer.VulnerabiltiesTitle() + writer.Content(vulnerabilitiesRows) + utils.JasMsg(writer.EntitledForJas()) + writer.Footer()
366+
return writer.VulnerabiltiesTitle(true) + writer.VulnerabilitiesContent(vulnerabilitiesRows) + writer.IacContent(iacRows) + utils.JasMsg(writer.EntitledForJas()) + writer.Footer()
347367
}

0 commit comments

Comments
 (0)