diff --git a/.golangci.yml b/.golangci.yml index 3501cb4d8..8656d11ed 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -49,6 +49,8 @@ linters-settings: - github.com/CheckmarxDev/containers-resolver/pkg/containerResolver - github.com/Checkmarx/manifest-parser/pkg/parser/models - github.com/Checkmarx/manifest-parser/pkg/parser + - github.com/Checkmarx/secret-detection/pkg/hooks/pre-commit + - github.com/Checkmarx/secret-detection/pkg/hooks/pre-receive - github.com/Checkmarx/gen-ai-prompts/prompts/sast_result_remediation - github.com/spf13/viper - github.com/Checkmarx/gen-ai-wrapper diff --git a/go.mod b/go.mod index fb6fce2ec..105ac00e9 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Checkmarx/gen-ai-prompts v0.0.0-20240807143411-708ceec12b63 github.com/Checkmarx/gen-ai-wrapper v1.0.2 github.com/Checkmarx/manifest-parser v0.0.6 - github.com/Checkmarx/secret-detection v0.0.3-0.20250327150305-31c2c3be9edf + github.com/Checkmarx/secret-detection v0.0.3-0.20250515130158-afa5bc2c67e3 github.com/MakeNowJust/heredoc v1.0.0 github.com/bouk/monkey v1.0.0 github.com/gofrs/flock v0.12.1 @@ -87,7 +87,7 @@ require ( github.com/charmbracelet/x/ansi v0.8.0 // indirect github.com/charmbracelet/x/cellbuf v0.0.13 // indirect github.com/charmbracelet/x/term v0.2.1 // indirect - github.com/checkmarx/2ms v1.4.1-0.20250327145719-b78804cb08c7 // indirect + github.com/checkmarx/2ms v1.4.1-0.20250409170516-73e15d33f92c // indirect github.com/cloudflare/circl v1.6.0 // indirect github.com/containerd/cgroups/v3 v3.0.5 // indirect github.com/containerd/containerd v1.7.27 // indirect @@ -130,7 +130,7 @@ require ( github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/github/go-spdx/v2 v2.3.2 // indirect - github.com/gitleaks/go-gitdiff v0.9.0 // indirect + github.com/gitleaks/go-gitdiff v0.9.1 // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect diff --git a/go.sum b/go.sum index 96a6ce465..0899511df 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,8 @@ github.com/Checkmarx/manifest-parser v0.0.6 h1:WgtygMTWUM+/3j/tE74BqV5yx9r+vm/g+ github.com/Checkmarx/manifest-parser v0.0.6/go.mod h1:s11sV8akqWX+H0MwFK3XBF8H6JohAjoQe8ClvdDFziQ= github.com/Checkmarx/secret-detection v0.0.3-0.20250327150305-31c2c3be9edf h1:lKiogedU3WzWBc/xI6Xj1BhX2Gp1QBJj8C+czY7CcaE= github.com/Checkmarx/secret-detection v0.0.3-0.20250327150305-31c2c3be9edf/go.mod h1:mtAHOm1mHGh7MVu6JdYUyitANsLcHNLUTBIh9pTERNI= +github.com/Checkmarx/secret-detection v0.0.3-0.20250515130158-afa5bc2c67e3 h1:In9Zw54S4+iKrJAX8MRHIrXwNUT/i8ut3+4YOOe+Dac= +github.com/Checkmarx/secret-detection v0.0.3-0.20250515130158-afa5bc2c67e3/go.mod h1:bnWrgf+52LUHpGeO570W6JjnoOM8S3bbfgxq27cgdEs= github.com/CycloneDX/cyclonedx-go v0.9.2 h1:688QHn2X/5nRezKe2ueIVCt+NRqf7fl3AVQk+vaFcIo= github.com/CycloneDX/cyclonedx-go v0.9.2/go.mod h1:vcK6pKgO1WanCdd61qx4bFnSsDJQ6SbM2ZuMIgq86Jg= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= @@ -218,6 +220,8 @@ github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQ github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/checkmarx/2ms v1.4.1-0.20250327145719-b78804cb08c7 h1:COsC3skOJeJaSoCPuhLZ0byRGKm+ZHlyw5qm9ydlab0= github.com/checkmarx/2ms v1.4.1-0.20250327145719-b78804cb08c7/go.mod h1:Bnd2YSh8LQSc4fHAFN0BKz8LYThB6qHg3Wn/+H+WZ4I= +github.com/checkmarx/2ms v1.4.1-0.20250409170516-73e15d33f92c h1:F1/Iv0HrerYKQCUPic8riZAbTUh+13b4i3UW8SD1yvE= +github.com/checkmarx/2ms v1.4.1-0.20250409170516-73e15d33f92c/go.mod h1:Bnd2YSh8LQSc4fHAFN0BKz8LYThB6qHg3Wn/+H+WZ4I= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= @@ -373,6 +377,8 @@ github.com/github/go-spdx/v2 v2.3.2 h1:IfdyNHTqzs4zAJjXdVQfRnxt1XMfycXoHBE2Vsm1b github.com/github/go-spdx/v2 v2.3.2/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ= github.com/gitleaks/go-gitdiff v0.9.0 h1:SHAU2l0ZBEo8g82EeFewhVy81sb7JCxW76oSPtR/Nqg= github.com/gitleaks/go-gitdiff v0.9.0/go.mod h1:pKz0X4YzCKZs30BL+weqBIG7mx0jl4tF1uXV9ZyNvrA= +github.com/gitleaks/go-gitdiff v0.9.1 h1:ni6z6/3i9ODT685OLCTf+s/ERlWUNWQF4x1pvoNICw0= +github.com/gitleaks/go-gitdiff v0.9.1/go.mod h1:pKz0X4YzCKZs30BL+weqBIG7mx0jl4tF1uXV9ZyNvrA= github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4= github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= diff --git a/internal/commands/hooks.go b/internal/commands/hooks.go new file mode 100644 index 000000000..b783981ac --- /dev/null +++ b/internal/commands/hooks.go @@ -0,0 +1,50 @@ +package commands + +import ( + "github.com/MakeNowJust/heredoc" + "github.com/checkmarx/ast-cli/internal/params" + "github.com/checkmarx/ast-cli/internal/wrappers" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +// NewHooksCommand creates the hooks command with pre-commit subcommand + +func NewHooksCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command { + hooksCmd := &cobra.Command{ + Use: "hooks", + Short: "Manage Git hooks", + Long: "The hooks command enables the ability to manage Git hooks for Checkmarx One.", + Example: heredoc.Doc( + ` + $ cx hooks pre-commit secrets-install-git-hook + $ cx hooks pre-commit secrets-scan + $ cx hooks pre-receive secrets-scan + `, + ), + Annotations: map[string]string{ + "command:doc": heredoc.Doc( + ` + https://checkmarx.com/resource/documents/en/xxxxx-xxxxx-hooks.html + `, + ), + }, + } + + // Add pre-commit and pre-receive subcommand + hooksCmd.AddCommand(PreCommitCommand(jwtWrapper)) + hooksCmd.AddCommand(PreReceiveCommand(jwtWrapper)) + + return hooksCmd +} + +func validateLicense(jwtWrapper wrappers.JWTWrapper) error { + allowed, err := jwtWrapper.IsAllowedEngine(params.EnterpriseSecretsLabel) + if err != nil { + return errors.Wrapf(err, "Failed checking license") + } + if !allowed { + return errors.New("Error: License validation failed. Please verify your CxOne license includes Enterprise Secrets.") + } + return nil +} diff --git a/internal/commands/pre-receive.go b/internal/commands/pre-receive.go new file mode 100644 index 000000000..063313423 --- /dev/null +++ b/internal/commands/pre-receive.go @@ -0,0 +1,49 @@ +package commands + +import ( + prereceive "github.com/Checkmarx/secret-detection/pkg/hooks/pre-receive" + "github.com/MakeNowJust/heredoc" + "github.com/checkmarx/ast-cli/internal/wrappers" + "github.com/spf13/cobra" +) + +func PreReceiveCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command { + preReceiveCmd := &cobra.Command{ + Use: "pre-receive", + Short: "Manage pre-receive hooks and run secret detection scans", + Long: "The pre-receive command enables the ability to manage Git pre-receive hooks for secret detection.", + Example: heredoc.Doc( + ` + $ cx hooks pre-receive secrets-scan + `, + ), + } + preReceiveCmd.AddCommand(scanSecretsPreReceiveCommand(jwtWrapper)) + + return preReceiveCmd +} + +func scanSecretsPreReceiveCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command { + var configFile string + scanPrereceiveCmd := &cobra.Command{ + Use: "secrets-scan", + Short: "Scan commits for secret detection.", + Long: "Scan all commits about to enter the remote git repository for secret detection.", + Example: heredoc.Doc( + ` + $ cx hooks pre-receive secrets-scan + $ cx hooks pre-receive secrets-scan --config /path/to/config.yaml + `, + ), + PreRunE: func(cmd *cobra.Command, args []string) error { + return validateLicense(jwtWrapper) + }, + RunE: func(cmd *cobra.Command, args []string) error { + return prereceive.Scan(configFile) + }, + } + + scanPrereceiveCmd.Flags().StringVarP(&configFile, "config", "c", "", "path to config.yaml file") + + return scanPrereceiveCmd +} diff --git a/internal/commands/pre_commit.go b/internal/commands/pre_commit.go index 950ca2ffc..08c2d20ea 100644 --- a/internal/commands/pre_commit.go +++ b/internal/commands/pre_commit.go @@ -2,42 +2,13 @@ package commands import ( "fmt" - precommit "github.com/Checkmarx/secret-detection/pkg/hooks" + precommit "github.com/Checkmarx/secret-detection/pkg/hooks/pre-commit" "github.com/MakeNowJust/heredoc" - "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/pkg/errors" "github.com/spf13/cobra" "strings" ) -// NewHooksCommand creates the hooks command with pre-commit subcommand -func NewHooksCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command { - hooksCmd := &cobra.Command{ - Use: "hooks", - Short: "Manage Git hooks", - Long: "The hooks command enables the ability to manage Git hooks for Checkmarx One.", - Example: heredoc.Doc( - ` - $ cx hooks pre-commit secrets-install-git-hook - $ cx hooks pre-commit secrets-scan - `, - ), - Annotations: map[string]string{ - "command:doc": heredoc.Doc( - ` - https://checkmarx.com/resource/documents/en/xxxxx-xxxxx-hooks.html - `, - ), - }, - } - - // Add pre-commit subcommand - hooksCmd.AddCommand(PreCommitCommand(jwtWrapper)) - - return hooksCmd -} - // PreCommitCommand creates the pre-commit subcommand func PreCommitCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command { preCommitCmd := &cobra.Command{ @@ -64,17 +35,6 @@ func PreCommitCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command { } // / validateLicense verifies the user has the required license for secret detection -func validateLicense(jwtWrapper wrappers.JWTWrapper) error { - - allowed, err := jwtWrapper.IsAllowedEngine(params.EnterpriseSecretsLabel) - if err != nil { - return errors.Wrapf(err, "Failed checking license") - } - if !allowed { - return errors.New("Error: License validation failed. Please verify your CxOne license includes Enterprise Secrets.") - } - return nil -} func secretsInstallGitHookCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command { cmd := &cobra.Command{