Skip to content

Commit 7dfa09a

Browse files
Merge branch 'main' into bug/update-containers-resolverrpm
2 parents 179b0ea + c8c5d78 commit 7dfa09a

32 files changed

+1471
-547
lines changed

go.mod

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/Checkmarx/containers-types v1.0.9
88
github.com/Checkmarx/gen-ai-prompts v0.0.0-20240807143411-708ceec12b63
99
github.com/Checkmarx/gen-ai-wrapper v1.0.2
10-
github.com/Checkmarx/manifest-parser v0.1.0
10+
github.com/Checkmarx/manifest-parser v0.1.1
1111
github.com/Checkmarx/secret-detection v1.2.1
1212
github.com/MakeNowJust/heredoc v1.0.0
1313
github.com/bouk/monkey v1.0.0
@@ -41,9 +41,6 @@ require (
4141
modernc.org/mathutil v1.7.1 // indirect
4242
modernc.org/memory v1.11.0 // indirect
4343
modernc.org/sqlite v1.38.2 // indirect
44-
)
45-
46-
require (
4744
dario.cat/mergo v1.0.1 // indirect
4845
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
4946
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20240914100643-eb91380d8434 // indirect
@@ -148,7 +145,7 @@ require (
148145
github.com/go-openapi/jsonreference v0.21.0 // indirect
149146
github.com/go-openapi/swag v0.23.1 // indirect
150147
github.com/go-restruct/restruct v1.2.0-alpha // indirect
151-
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
148+
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
152149
github.com/gobwas/glob v0.2.3 // indirect
153150
github.com/gogo/protobuf v1.3.2 // indirect
154151
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ github.com/Checkmarx/gen-ai-prompts v0.0.0-20240807143411-708ceec12b63 h1:SCuTcE
7575
github.com/Checkmarx/gen-ai-prompts v0.0.0-20240807143411-708ceec12b63/go.mod h1:MI6lfLerXU+5eTV/EPTDavgnV3owz3GPT4g/msZBWPo=
7676
github.com/Checkmarx/gen-ai-wrapper v1.0.2 h1:T6X40+4hYnwfDsvkjWs9VIcE6s1O+8DUu0+sDdCY3GI=
7777
github.com/Checkmarx/gen-ai-wrapper v1.0.2/go.mod h1:xwRLefezwNNnRGu1EjGS6wNiR9FVV/eP9D+oXwLViVM=
78-
github.com/Checkmarx/manifest-parser v0.1.0 h1:swnzQpBFbJap7dgoj39oI6MaIqUlnVuBp5VJzeLVevQ=
79-
github.com/Checkmarx/manifest-parser v0.1.0/go.mod h1:hh5FX5FdDieU8CKQEkged4hfOaSylpJzub8PRFXa4kA=
78+
github.com/Checkmarx/manifest-parser v0.1.1 h1:Yp/fy0NjeLxxcS8y9AA9yIzWafC/Zeqn36YjVSe91DU=
79+
github.com/Checkmarx/manifest-parser v0.1.1/go.mod h1:hh5FX5FdDieU8CKQEkged4hfOaSylpJzub8PRFXa4kA=
8080
github.com/Checkmarx/secret-detection v1.2.1 h1:Hzpz74dcN/L14Q86ARvPOZpKBnERzGTpy6sl1RXKOTo=
8181
github.com/Checkmarx/secret-detection v1.2.1/go.mod h1:kbXbtIQisDdB/TNuV7r9HPclEznUyBHLQ5yr7IX7vBQ=
8282
github.com/CycloneDX/cyclonedx-go v0.9.2 h1:688QHn2X/5nRezKe2ueIVCt+NRqf7fl3AVQk+vaFcIo=
@@ -421,8 +421,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ
421421
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
422422
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
423423
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
424-
github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
425-
github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
424+
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
425+
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
426426
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
427427
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
428428
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=

internal/commands/predicates.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package commands
22

33
import (
4+
"strings"
5+
"time"
6+
47
"github.com/MakeNowJust/heredoc"
58
"github.com/checkmarx/ast-cli/internal/commands/util/printer"
69
"github.com/checkmarx/ast-cli/internal/params"
710
"github.com/checkmarx/ast-cli/internal/wrappers"
811
"github.com/pkg/errors"
912
"github.com/spf13/cobra"
10-
"strings"
11-
"time"
1213
)
1314

1415
var systemStates = []wrappers.CustomState{

internal/commands/predicates_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ package commands
44

55
import (
66
"fmt"
7+
"testing"
8+
79
"github.com/checkmarx/ast-cli/internal/wrappers"
810
"github.com/checkmarx/ast-cli/internal/wrappers/mock"
9-
"testing"
1011

1112
"gotest.tools/assert"
1213
)

internal/commands/result.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ func exportGlSastResults(targetFile string, results *wrappers.ScanResultsCollect
16621662
if err != nil {
16631663
return errors.Wrapf(err, "%s: failed to add scan to gl-sast report", failedListingResults)
16641664
}
1665-
convertCxResultToGlSastVulnerability(results, glSast, summary.BaseURI)
1665+
convertCxResultToGlSastVulnerability(results, glSast, summary)
16661666
resultsJSON, err := json.Marshal(glSast)
16671667
if err != nil {
16681668
return errors.Wrapf(err, "%s: failed to serialize gl-sast report ", failedListingResults)
@@ -2031,10 +2031,10 @@ func convertCxResultsToSarif(results *wrappers.ScanResultsCollection) *wrappers.
20312031
return sarif
20322032
}
20332033

2034-
func convertCxResultToGlSastVulnerability(results *wrappers.ScanResultsCollection, glSast *wrappers.GlSastResultsCollection, summaryBaseURI string) {
2034+
func convertCxResultToGlSastVulnerability(results *wrappers.ScanResultsCollection, glSast *wrappers.GlSastResultsCollection, summary *wrappers.ResultSummary) {
20352035
for _, result := range results.Results {
20362036
if strings.TrimSpace(result.Type) == commonParams.SastType {
2037-
glSast = parseGlSastVulnerability(result, glSast, summaryBaseURI)
2037+
glSast = parseGlSastVulnerability(result, glSast, summary)
20382038
}
20392039
}
20402040
}
@@ -2054,7 +2054,9 @@ func convertCxResultToGlScaFiles(results *wrappers.ScanResultsCollection, glScaR
20542054
}
20552055
}
20562056
}
2057-
func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSastResultsCollection, summaryBaseURI string) *wrappers.GlSastResultsCollection {
2057+
func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSastResultsCollection, summary *wrappers.ResultSummary) *wrappers.GlSastResultsCollection {
2058+
hostName := parseURI(summary.BaseURI)
2059+
20582060
queryName := result.ScanResultData.QueryName
20592061
fileName := result.ScanResultData.Nodes[0].FileName
20602062
lineNumber := strconv.FormatUint(uint64(result.ScanResultData.Nodes[0].Line), 10)
@@ -2063,13 +2065,14 @@ func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSa
20632065
ID := fmt.Sprintf("%s:%s:%s", queryName, fileName, lineNumber)
20642066
category := fmt.Sprintf("%s-%s", wrappers.VendorName, result.Type)
20652067
message := fmt.Sprintf("%s@%s:%s", queryName, fileName, lineNumber)
2068+
QueryDescriptionLink := fmt.Sprintf("%s/results/%s/%s/sast/description/%s/%s", hostName, summary.ScanID, summary.ProjectID, result.VulnerabilityDetails.CweID, result.ScanResultData.QueryID)
20662069

20672070
glSast.Vulnerabilities = append(glSast.Vulnerabilities, wrappers.GlVulnerabilities{
20682071
ID: ID,
20692072
Category: category,
20702073
Name: queryName,
20712074
Message: message,
2072-
Description: result.Description,
2075+
Description: result.Description + " \n" + QueryDescriptionLink,
20732076
CVE: ID,
20742077
Severity: cases.Title(language.English).String(result.Severity),
20752078
Confidence: cases.Title(language.English).String(result.Severity),
@@ -2083,7 +2086,7 @@ func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSa
20832086
{
20842087
Type: "cxOneScan",
20852088
Name: "CxOne Scan",
2086-
URL: summaryBaseURI,
2089+
URL: summary.BaseURI,
20872090
Value: result.ID,
20882091
},
20892092
},
@@ -2889,6 +2892,16 @@ type ScannerResponse struct {
28892892
ErrorCode string `json:"ErrorCode,omitempty"`
28902893
}
28912894

2895+
func parseURI(summaryBaseURI string) (hostName string) {
2896+
parsedURL, err := url.Parse(summaryBaseURI)
2897+
if err != nil {
2898+
return ""
2899+
}
2900+
hostName = fmt.Sprintf("%s://%s", parsedURL.Scheme, parsedURL.Host)
2901+
2902+
return hostName
2903+
}
2904+
28922905
func printWarningIfIgnorePolicyOmiited() {
28932906
fmt.Printf("\n Warning: The --ignore-policy flag was not implemented because you don’t have the required permission.\n Only users with 'override-policy-management' permission can use this flag. \n\n")
28942907
}

internal/commands/result_test.go

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ func TestRunGetResultsByScanIdSummaryConsoleFormat_ScsCompleted_ScsCompletedInRe
10951095
"Expected SCS summary:"+scsSummary)
10961096
secretDetectionSummary := secretDetectionLine
10971097
assert.Equal(t, strings.Contains(cleanString, secretDetectionSummary), true,
1098-
"Expected Secret Detection summary:"+secretDetectionSummary)
1098+
"Expected Secret Detection summary:"+secretDetectionLine)
10991099
scorecardSummary := "| Scorecard 0 0 0 1 0 Completed |"
11001100
assert.Equal(t, strings.Contains(cleanString, scorecardSummary), true,
11011101
"Expected Scorecard summary:"+scorecardSummary)
@@ -1130,7 +1130,7 @@ func TestRunGetResultsByScanIdSummaryConsoleFormat_ScsPartial_ScsPartialInReport
11301130
"Expected SCS summary:"+scsSummary)
11311131
secretDetectionSummary := secretDetectionLine
11321132
assert.Equal(t, strings.Contains(cleanString, secretDetectionSummary), true,
1133-
"Expected Secret Detection summary:"+secretDetectionSummary)
1133+
"Expected Secret Detection summary:"+secretDetectionLine)
11341134
scorecardSummary := " | Scorecard 0 0 0 0 0 Failed |"
11351135
assert.Equal(t, strings.Contains(cleanString, scorecardSummary), true,
11361136
"Expected Scorecard summary:"+scorecardSummary)
@@ -1157,7 +1157,7 @@ func TestRunGetResultsByScanIdSummaryConsoleFormat_ScsScorecardNotScanned_Scorec
11571157
"Expected SCS summary:"+scsSummary)
11581158
secretDetectionSummary := secretDetectionLine
11591159
assert.Equal(t, strings.Contains(stdoutString, secretDetectionSummary), true,
1160-
"Expected Secret Detection summary:"+secretDetectionSummary)
1160+
"Expected Secret Detection summary:"+secretDetectionLine)
11611161
scorecardSummary := "| Scorecard - - - - - - |"
11621162
assert.Equal(t, strings.Contains(stdoutString, scorecardSummary), true,
11631163
"Expected Scorecard summary:"+scorecardSummary)
@@ -1697,3 +1697,77 @@ func TestIgnorePolicyWithPermission(t *testing.T) {
16971697
output := buf.String()
16981698
assert.Assert(t, !strings.Contains(output, "Warning: The --ignore-policy flag was not implemented because you don’t have the required permission."), "'Ignore Policy flag omitted because you dont have permission' should not be present in the output")
16991699
}
1700+
1701+
func TestParseGlSastVulnerability_QueryDescriptionLink_Succeed(t *testing.T) {
1702+
mockResult := createMockScanResult("q1234", "c5678")
1703+
glSast := &wrappers.GlSastResultsCollection{}
1704+
summary := &wrappers.ResultSummary{
1705+
BaseURI: "https://example.com/overview",
1706+
ScanID: "scanID",
1707+
ProjectID: "projectID",
1708+
}
1709+
expectedURL := "https://example.com/results/scanID/projectID/sast/description/c5678/q1234"
1710+
1711+
glSast = parseGlSastVulnerability(mockResult, glSast, summary)
1712+
1713+
assert.Assert(t, len(glSast.Vulnerabilities) > 0)
1714+
1715+
actualURL := extractURLFromDescription(glSast.Vulnerabilities[0].Description)
1716+
1717+
assert.Equal(t, actualURL, expectedURL, "QueryDescriptionLink URL does not match expected format")
1718+
}
1719+
1720+
func TestParseGlSastVulnerability_QueryDescriptionLink_Negative(t *testing.T) {
1721+
mockResult := createMockScanResult("", "")
1722+
glSast := &wrappers.GlSastResultsCollection{}
1723+
summary := &wrappers.ResultSummary{
1724+
BaseURI: "invalid-url",
1725+
ScanID: "scanID",
1726+
ProjectID: "projectID",
1727+
}
1728+
expectedPattern := "/results/scanID/projectID/sast/description//"
1729+
1730+
glSast = parseGlSastVulnerability(mockResult, glSast, summary)
1731+
1732+
assert.Assert(t, len(glSast.Vulnerabilities) > 0)
1733+
vuln := glSast.Vulnerabilities[0]
1734+
1735+
assert.Assert(t, strings.Contains(vuln.Description, expectedPattern),
1736+
"URL should contain pattern with empty values")
1737+
1738+
actualURL := extractURLFromDescription(vuln.Description)
1739+
assert.Assert(t, actualURL != "", "Extracted URL should not be empty")
1740+
}
1741+
1742+
func createMockScanResult(queryID, cweID string) *wrappers.ScanResult {
1743+
return &wrappers.ScanResult{
1744+
Type: "sast",
1745+
ScanResultData: wrappers.ScanResultData{
1746+
QueryName: "TestQuery",
1747+
QueryID: queryID,
1748+
Nodes: []*wrappers.ScanResultNode{
1749+
{
1750+
FileName: "file.go",
1751+
Line: 42,
1752+
Length: 1,
1753+
},
1754+
},
1755+
},
1756+
VulnerabilityDetails: wrappers.VulnerabilityDetails{
1757+
CweID: cweID,
1758+
},
1759+
ID: "vuln-1",
1760+
Description: "desc-",
1761+
Severity: "high",
1762+
}
1763+
}
1764+
1765+
func extractURLFromDescription(description string) string {
1766+
parts := strings.Split(description, "http")
1767+
if len(parts) == 1 {
1768+
return "http" + strings.Split(parts[0], " ")[0]
1769+
} else if len(parts) > 1 {
1770+
return "http" + strings.Split(parts[1], " ")[0]
1771+
}
1772+
return ""
1773+
}

0 commit comments

Comments
 (0)