Skip to content

Commit 1fe1f1c

Browse files
cx-itay-pazItay Paz
andauthored
Add ignore file path flag and tests for ossRealtime(AST-103853) (#1214)
* Add ignore file path flag and tests * fix complexity * fix lint * use getid * fix lint * fix unit test --------- Co-authored-by: Itay Paz <[email protected]>
1 parent cd59749 commit 1fe1f1c

File tree

11 files changed

+202
-15
lines changed

11 files changed

+202
-15
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"PackageManager": "npm",
4+
"PackageName": "coa",
5+
"PackageVersion": "3.1.3"
6+
}
7+
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"PackageManager": "nuget",
4+
"PackageName": "Microsoft.Extensions.Caching.Memory",
5+
"PackageVersion": "6.0.3"
6+
}
7+
]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[
2+
3+
]

internal/commands/data/manifests/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
"@CheckmarxDev/ast-cli-javascript-wrapper": "file:../ast-cli-javascript-wrapper/CheckmarxDev-ast-cli-javascript-wrapper-0.0.54.tgz",
44
"@checkmarxdev/ast-cli-javascript-wrapper": "0.0.54",
55
"copyfiles": "200",
6-
"tree-kill": "^1.2.2"
6+
"tree-kill": "^1.2.2",
7+
"coa":"3.1.3"
8+
79
},
810
"description": "Beat vulnerabilities with more-secure code",
911
"devDependencies": {

internal/commands/data/manifests/test.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
<Version>19.225.1</Version>
3535
</PackageReference>
3636
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.0.32112.339" />
37+
<PackageReference Include="Microsoft.Extensions.Caching.Memory">
38+
<Version>6.0.1</Version>
39+
</PackageReference>
3740
<PackageReference Include="System.Json" Version="4.7.1" />
3841
</ItemGroup>
3942
<ItemGroup>

internal/commands/oss-realtime-engine.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,26 @@ import (
99
"github.com/spf13/cobra"
1010
)
1111

12-
func RunScanOssRealtimeCommand(realtimeScannerWrapper wrappers.RealtimeScannerWrapper,
12+
func RunScanOssRealtimeCommand(
13+
realtimeScannerWrapper wrappers.RealtimeScannerWrapper,
1314
jwtWrapper wrappers.JWTWrapper,
14-
featureFlagWrapper wrappers.FeatureFlagsWrapper) func(cmd *cobra.Command, args []string) error {
15+
featureFlagWrapper wrappers.FeatureFlagsWrapper,
16+
) func(cmd *cobra.Command, args []string) error {
1517
return func(cmd *cobra.Command, _ []string) error {
1618
fileSourceFlag, _ := cmd.Flags().GetString(commonParams.SourcesFlag)
1719
if fileSourceFlag == "" {
1820
return errorconstants.NewRealtimeEngineError("file path is required").Error()
1921
}
22+
23+
ignoredFilePathFlag, _ := cmd.Flags().GetString(commonParams.IgnoredFilePathFlag)
24+
2025
ossRealtimeService := ossrealtime.NewOssRealtimeService(jwtWrapper, featureFlagWrapper, realtimeScannerWrapper)
2126

22-
packages, err := ossRealtimeService.RunOssRealtimeScan(fileSourceFlag)
27+
packages, err := ossRealtimeService.RunOssRealtimeScan(fileSourceFlag, ignoredFilePathFlag)
2328
if err != nil {
2429
return err
2530
}
31+
2632
err = printer.Print(cmd.OutOrStdout(), packages, printer.FormatJSON)
2733
if err != nil {
2834
return errorconstants.NewRealtimeEngineError("failed to return packages").Error()

internal/commands/scan.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,22 +454,26 @@ func scanASCASubCommand(jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrap
454454
return scanASCACmd
455455
}
456456

457-
func scanOssRealtimeSubCommand(realtimeScannerWrapper wrappers.RealtimeScannerWrapper, jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) *cobra.Command {
457+
func scanOssRealtimeSubCommand(
458+
realtimeScannerWrapper wrappers.RealtimeScannerWrapper,
459+
jwtWrapper wrappers.JWTWrapper,
460+
featureFlagsWrapper wrappers.FeatureFlagsWrapper,
461+
) *cobra.Command {
458462
scanOssRealtimeCmd := &cobra.Command{
459463
Hidden: true,
460464
Use: "oss-realtime",
461465
Short: "Run a OSS-Realtime scan",
462466
Long: "Running a OSS-Realtime scan is a fast and efficient way to identify malicious packages in a manifest file",
463467
Example: heredoc.Doc(
464468
`
465-
$ cx scan oss-realtime -s <path to a manifest files separated by commas>
466-
`,
469+
$ cx scan oss-realtime -s <path to a manifest file> --ignored-file-path <path to ignored packages JSON>
470+
`,
467471
),
468472
Annotations: map[string]string{
469473
"command:doc": heredoc.Doc(
470474
`
471475
https://docs.checkmarx.com/en/34965-68625-checkmarx-one-cli-commands.html
472-
`,
476+
`,
473477
),
474478
},
475479
RunE: RunScanOssRealtimeCommand(realtimeScannerWrapper, jwtWrapper, featureFlagsWrapper),
@@ -481,6 +485,13 @@ func scanOssRealtimeSubCommand(realtimeScannerWrapper wrappers.RealtimeScannerWr
481485
"",
482486
"The file source should be the path to a single file or multiple files separated by commas",
483487
)
488+
489+
scanOssRealtimeCmd.Flags().String(
490+
commonParams.IgnoredFilePathFlag,
491+
"",
492+
"Path to a JSON file listing ignored packages",
493+
)
494+
484495
return scanOssRealtimeCmd
485496
}
486497

internal/params/flags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const (
1818
RetryDelayPollingDefault = 60
1919
RetryDelayUsage = "Time between retries in seconds, use with --" + RetryFlag
2020
SourcesFlag = "file-source"
21+
IgnoredFilePathFlag = "ignored-file-path"
2122
SourcesFlagSh = "s"
2223
TenantFlag = "tenant"
2324
TenantFlagUsage = "Checkmarx tenant"

internal/services/realtimeengine/ossrealtime/config.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package ossrealtime
22

3-
import "github.com/checkmarx/ast-cli/internal/services/realtimeengine"
3+
import (
4+
"fmt"
5+
6+
"github.com/checkmarx/ast-cli/internal/services/realtimeengine"
7+
)
48

59
// OssPackage represents a package's details for OSS scanning.
610
type OssPackage struct {
@@ -18,6 +22,24 @@ type OssPackageResults struct {
1822
Packages []OssPackage `json:"Packages"`
1923
}
2024

25+
func composeID(packageManager, packageName, packageVersion string) string {
26+
return fmt.Sprintf("%s_%s_%s", packageManager, packageName, packageVersion)
27+
}
28+
29+
func (p *OssPackage) GetID() string {
30+
return composeID(p.PackageManager, p.PackageName, p.PackageVersion)
31+
}
32+
33+
type IgnoredPackage struct {
34+
PackageManager string `json:"PackageManager"`
35+
PackageName string `json:"PackageName"`
36+
PackageVersion string `json:"PackageVersion"`
37+
}
38+
39+
func (p IgnoredPackage) GetID() string {
40+
return composeID(p.PackageManager, p.PackageName, p.PackageVersion)
41+
}
42+
2143
type Vulnerability struct {
2244
CVE string `json:"CVE"`
2345
Description string `json:"Description"`

internal/services/realtimeengine/ossrealtime/oss-realtime.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package ossrealtime
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"os"
57
"strings"
68

79
"github.com/Checkmarx/manifest-parser/pkg/parser"
@@ -48,7 +50,7 @@ func NewOssRealtimeService(
4850
}
4951

5052
// RunOssRealtimeScan performs an OSS real-time scan on the given manifest file.
51-
func (o *OssRealtimeService) RunOssRealtimeScan(filePath string) (*OssPackageResults, error) {
53+
func (o *OssRealtimeService) RunOssRealtimeScan(filePath, ignoredFilePath string) (*OssPackageResults, error) {
5254
if filePath == "" {
5355
return nil, errorconstants.NewRealtimeEngineError("file path is required").Error()
5456
}
@@ -79,9 +81,56 @@ func (o *OssRealtimeService) RunOssRealtimeScan(filePath string) (*OssPackageRes
7981
packageMap := createPackageMap(pkgs)
8082
enrichResponseWithRealtimeScannerResults(response, result, packageMap)
8183
}
84+
85+
if ignoredFilePath != "" {
86+
ignoredPkgs, err := loadIgnoredPackages(ignoredFilePath)
87+
if err != nil {
88+
return nil, errorconstants.NewRealtimeEngineError("failed to load ignored packages").Error()
89+
}
90+
91+
ignoreMap := buildIgnoreMap(ignoredPkgs)
92+
response.Packages = filterIgnoredPackages(response.Packages, ignoreMap)
93+
}
94+
8295
return response, nil
8396
}
8497

98+
func buildIgnoreMap(ignored []IgnoredPackage) map[string]bool {
99+
m := make(map[string]bool)
100+
for _, ign := range ignored {
101+
m[ign.GetID()] = true
102+
}
103+
return m
104+
}
105+
106+
func isIgnored(pkg *OssPackage, ignoreMap map[string]bool) bool {
107+
return ignoreMap[pkg.GetID()]
108+
}
109+
110+
func loadIgnoredPackages(path string) ([]IgnoredPackage, error) {
111+
data, err := os.ReadFile(path)
112+
if err != nil {
113+
return nil, err
114+
}
115+
var ignored []IgnoredPackage
116+
err = json.Unmarshal(data, &ignored)
117+
if err != nil {
118+
return nil, err
119+
}
120+
return ignored, nil
121+
}
122+
123+
func filterIgnoredPackages(packages []OssPackage, ignoreMap map[string]bool) []OssPackage {
124+
filtered := make([]OssPackage, 0, len(packages))
125+
for i := range packages {
126+
pkg := &packages[i]
127+
if !isIgnored(pkg, ignoreMap) {
128+
filtered = append(filtered, *pkg)
129+
}
130+
}
131+
return filtered
132+
}
133+
85134
func enrichResponseWithRealtimeScannerResults(
86135
response *OssPackageResults,
87136
result *wrappers.RealtimeScannerPackageResponse,

0 commit comments

Comments
 (0)