GitLab Checkmarx CI/CD Integration
Overview
Purpose
Checkmarx is a good tool to do code analysis, but there are 2 pain points during the flow.
- Checkmarx can integrate SCM like GitHub/GitLab/..., but it cannot be triggered by by a code commit, it can only schedule the job to run the scan. (If I don't commit code, I don't want to waste resources scanning the code.)
- Checkmarx has a built-in issue tracking system, but I think most people prefer to use their issue tracking system in their Git or JIRA or ...
What we want is to integrate Checkmarx scan into GitLab's CI/CD flow including
- When we commit code to GitLab, it will trigger Checkmarx to scan automatically.
- After the scan, Checkmarx will create issues in GitLab.
Procedure
GitLab admin configuration
- You need to set some global variables in GitLab CI/CD admin (Menu->Admin->Settings->CI/CD->Variables). You need to set CHECKMARX_XXX and CX_TEAM variables to integrate Checkmarx. And if you want Checkmarx to create GitLab issue, please also set GITLAB_URL and GITLAB_TOKEN. (You can reference here for the detail)
GitLab project configuration
-
It's very easy to enable Checkmarx analysis in your GitLab jobs, you just need to edit your .gitlab-ci.yml and include Checkmarx's yml into it (line 1). And you also need to assign Checkmarx's project name in this yml file (line 4).
1include: 'https://raw.githubusercontent.com/checkmarx-ltd/cx-flow/develop/templates/gitlab/v3/Checkmarx.gitlab-ci.yml' 2 3variables: 4 CX_PROJECT: ProjectXXX #The project name you want to show in Checkmarx
-
Then you can try to commit code to trigger a CI/CD flow, Checkmarx analysis will be triggered in 2 conditions:
- When you create a merge request in GitLab.
- When you commit code to master stream directly.
The following is a log sample, please check line 20, you can see the variables you defined in GitLab.
1Running with gitlab-runner 14.5.2 (e91107dd) 2 on Runner in PC vYY9jCrR 3Preparing the "docker" executor 400:06 5Using Docker executor with image checkmarx/cx-flow ... 6Pulling docker image checkmarx/cx-flow ... 7Using docker image sha256:22f48d49aa64275d09b1650c359c0a9b1ab9fa771efa01fba4af89f511b93481 for checkmarx/cx-flow with digest checkmarx/cx-flow@sha256:2b2a2f09680e6c3ba21b00cf8ab4005baa133f0eeeaeb406f09b01a832fffb67 ... 8Preparing environment 900:01 10Running on runner-vyy9jcrr-project-33-concurrent-0 via 435566b8ed7c... 11Getting source from Git repository 1200:14 13Fetching changes... 14 15...... 16 17 18Executing "step_script" stage of the job script 19Using docker image sha256:22f48d49aa64275d09b1650c359c0a9b1ab9fa771efa01fba4af89f511b93481 for checkmarx/cx-flow with digest checkmarx/cx-flow@sha256:2b2a2f09680e6c3ba21b00cf8ab4005baa133f0eeeaeb406f09b01a832fffb67 ... 20$ ${CX_FLOW_EXE} --scan --app="${CI_PROJECT_NAME}" --namespace="${CI_PROJECT_NAMESPACE}" --repo-name="${CI_PROJECT_NAME}" --repo-url="${CI_REPOSITORY_URL}" --cx-team="${CX_TEAM}" --cx-project="${CX_PROJECT}" --branch="${CI_COMMIT_BRANCH}" --spring.profiles.active="${CX_FLOW_ENABLED_VULNERABILITY_SCANNERS}" --f=. ${PARAMS} 21SLF4J: Class path contains multiple SLF4J bindings. 22SLF4J: Found binding in [jar:file:/app/cx-flow.jar!/BOOT-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] 23SLF4J: Found binding in [jar:file:/app/cx-flow.jar!/BOOT-INF/lib/log4j-slf4j-impl-2.17.1.jar!/org/slf4j/impl/StaticLoggerBinder.class] 24SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. 25SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder] 26 ___ ___ _ 27 / __\_ __ / __\ | _____ __ 28 / / \ \/ /____ / _\ | |/ _ \ \ /\ / / 29/ /___ > <_____/ / | | (_) \ V V / 30\____//_/\_\ \/ |_|\___/ \_/\_/ 312022-01-21 06:44:09.841 WARN 11 --- [ main] o.s.b.StartupInfoLogger [] : InetAddress.getLocalHost().getHostName() took 5006 milliseconds to respond. Please verify your network configuration. 322022-01-21 06:44:14.858 INFO 11 --- [ main] c.c.f.CxFlowApplication [] : Starting CxFlowApplication with PID 11 (/app/cx-flow.jar started by root in /builds/*********) 332022-01-21 06:44:14.858 INFO 11 --- [ main] c.c.f.CxFlowApplication [] : The following profiles are active: sast 342022-01-21 06:44:18.305 INFO 11 --- [ main] ptablePropertiesBeanFactoryPostProcessor [] : Post-processing PropertySource instances 352022-01-21 06:44:18.464 INFO 11 --- [ main] c.u.j.EncryptablePropertySourceConverter [] : Converting PropertySource configurationProperties [org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource] to AOP Proxy 362022-01-21 06:44:18.467 INFO 11 --- [ main] c.u.j.EncryptablePropertySourceConverter [] : Converting PropertySource commandLineArgs [org.springframework.core.env.SimpleCommandLinePropertySource] to EncryptableEnumerablePropertySourceWrapper 372022-01-21 06:44:18.467 INFO 11 --- [ main] c.u.j.EncryptablePropertySourceConverter [] : Converting PropertySource systemProperties [org.springframework.core.env.PropertiesPropertySource] to EncryptableMapPropertySourceWrapper 382022-01-21 06:44:18.468 INFO 11 --- [ main] c.u.j.EncryptablePropertySourceConverter [] : Converting PropertySource systemEnvironment [org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource] to EncryptableSystemEnvironmentPropertySourceWrapper 392022-01-21 06:44:18.468 INFO 11 --- [ main] c.u.j.EncryptablePropertySourceConverter [] : Converting PropertySource random [org.springframework.boot.env.RandomValuePropertySource] to EncryptablePropertySourceWrapper 402022-01-21 06:44:18.469 INFO 11 --- [ main] c.u.j.EncryptablePropertySourceConverter [] : Converting PropertySource applicationConfig: [classpath:/application-sast.yml] [org.springframework.boot.env.OriginTrackedMapPropertySource] to EncryptableMapPropertySourceWrapper 412022-01-21 06:44:18.469 INFO 11 --- [ main] c.u.j.EncryptablePropertySourceConverter [] : Converting PropertySource applicationConfig: [classpath:/application.yml] [org.springframework.boot.env.OriginTrackedMapPropertySource] to EncryptableMapPropertySourceWrapper 422022-01-21 06:44:18.607 INFO 11 --- [ main] c.u.j.f.DefaultLazyPropertyFilter [] : Property Filter custom Bean not found with name 'encryptablePropertyFilter'. Initializing Default Property Filter 432022-01-21 06:44:18.620 INFO 11 --- [ main] c.u.j.r.DefaultLazyPropertyResolver [] : Property Resolver custom Bean not found with name 'encryptablePropertyResolver'. Initializing Default Property Resolver 442022-01-21 06:44:18.629 INFO 11 --- [ main] c.u.j.d.DefaultLazyPropertyDetector [] : Property Detector custom Bean not found with name 'encryptablePropertyDetector'. Initializing Default Property Detector 452022-01-21 06:44:18.934 WARN 11 --- [ main] j.p.spi [] : javax.persistence.spi::No valid providers found. 462022-01-21 06:44:18.938 INFO 11 --- [ main] trationDelegate$BeanPostProcessorChecker [] : Bean 'org.hibernate.validator.internal.constraintvalidators.bv.NotBlankValidator' of type [org.hibernate.validator.internal.constraintvalidators.bv.NotBlankValidator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 472022-01-21 06:44:18.942 INFO 11 --- [ main] trationDelegate$BeanPostProcessorChecker [] : Bean 'org.hibernate.validator.internal.constraintvalidators.bv.NotNullValidator' of type [org.hibernate.validator.internal.constraintvalidators.bv.NotNullValidator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 482022-01-21 06:44:18.944 INFO 11 --- [ main] trationDelegate$BeanPostProcessorChecker [] : Bean 'flowProperties' of type [com.checkmarx.flow.config.FlowProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 492022-01-21 06:44:18.947 INFO 11 --- [ main] trationDelegate$BeanPostProcessorChecker [] : Bean 'flowAsyncConfig' of type [com.checkmarx.flow.config.FlowAsyncConfig$$EnhancerBySpringCGLIB$$9e6d5344] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 502022-01-21 06:44:22.959 INFO 11 --- [ main] o.s.w.s.s.SaajSoapMessageFactory [] : Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol 512022-01-21 06:44:23.569 INFO 11 --- [ main] o.s.s.c.ThreadPoolTaskExecutor [] : Initializing ExecutorService 522022-01-21 06:44:23.571 INFO 11 --- [ main] o.s.s.c.ThreadPoolTaskExecutor [] : Initializing ExecutorService 'scanRequest' 532022-01-21 06:44:23.576 INFO 11 --- [ main] o.s.s.c.ThreadPoolTaskExecutor [] : Initializing ExecutorService 542022-01-21 06:44:23.577 INFO 11 --- [ main] o.s.s.c.ThreadPoolTaskExecutor [] : Initializing ExecutorService 'webHook' 552022-01-21 06:44:23.790 INFO 11 --- [ main] c.c.f.CxFlowRunner [] : =======BUILD INFO======= 562022-01-21 06:44:23.791 INFO 11 --- [ main] c.c.f.CxFlowRunner [] : Version: cx-flow-1.6.29 572022-01-21 06:44:23.792 INFO 11 --- [ main] c.c.f.CxFlowRunner [] : Time: 2022-01-07T12:45:49.239Z 582022-01-21 06:44:23.793 INFO 11 --- [ main] c.c.f.CxFlowRunner [] : ======================= 592022-01-21 06:44:25.426 INFO 11 --- [ main] c.c.f.CxFlowApplication [] : Started CxFlowApplication in 32.909 seconds (JVM running for 34.89) 602022-01-21 06:44:25.457 INFO 11 --- [ main] c.c.f.CxFlowRunner [blKXd4Ey] : Using custom bean implementation for bug tracking 612022-01-21 06:44:25.539 INFO 11 --- [ main] c.c.f.s.ScaFilterFactory [blKXd4Ey] : Initializing SCA filters. 622022-01-21 06:44:25.541 INFO 11 --- [ main] c.c.f.CxFlowRunner [blKXd4Ey] : Executing scan process 632022-01-21 06:44:25.551 INFO 11 --- [ main] c.c.f.s.ScaFilterFactory [blKXd4Ey] : Initializing SCA filters. 642022-01-21 06:44:25.571 INFO 11 --- [ main] c.c.f.s.ProjectNameGenerator [blKXd4Ey] : Project name being used: ********* 652022-01-21 06:44:25.573 INFO 11 --- [ main] c.c.f.u.ZipUtils [blKXd4Ey] : Creating zip file /builds/*********/cx.1357f707-5066-486c-b6f5-1d9dc08a4ad9.zip from contents of path . 662022-01-21 06:44:25.573 INFO 11 --- [ main] c.c.f.u.ZipUtils [blKXd4Ey] : Applying exclusions: .jar 672022-01-21 06:44:47.686 INFO 11 --- [ main] c.c.f.u.ZipUtils [blKXd4Ey] : Successfully created /builds/*********/cx.1357f707-5066-486c-b6f5-1d9dc08a4ad9.zip 682022-01-21 06:44:47.688 INFO 11 --- [ main] c.c.f.s.ScanRequestConverter [blKXd4Ey] : Overriding team with /CxServer/TEAM*** 692022-01-21 06:44:47.702 INFO 11 --- [ main] c.c.s.s.CxAuthService [blKXd4Ey] : Logging into Checkmarx https://***.com/cxrestapi/auth/identity/connect/token 702022-01-21 06:44:48.665 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Retrieving Cx teams 712022-01-21 06:44:48.700 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Found team /CxServer/TEAM*** with ID 16 722022-01-21 06:44:48.920 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Creating scan... 732022-01-21 06:44:48.921 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Updating Source details for project Id 67 742022-01-21 06:45:05.838 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Scan will be Full Scan 752022-01-21 06:45:05.840 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Creating Scan for project Id 67 762022-01-21 06:45:06.021 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Scan created with Id 1000207 for project Id 67 772022-01-21 06:45:06.171 INFO 11 --- [ main] jsonLogger [blKXd4Ey] : 782022-01-21 07:22:12.549 INFO 11 --- [ main] jsonLogger [blKXd4Ey] : 792022-01-21 07:22:12.551 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Creating report for xml Id 1000207 802022-01-21 07:22:12.906 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Report with Id 304 created 812022-01-21 07:22:17.908 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Retrieving report status of report Id 304 822022-01-21 07:22:18.965 INFO 11 --- [ main] c.c.s.s.CxAuthService [blKXd4Ey] : Logging into Checkmarx for SOAP token https://***.com/cxrestapi/auth/identity/connect/token 832022-01-21 07:22:19.117 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Retrieving report contents of report Id 304 in XML format 842022-01-21 07:22:19.220 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Report downloaded for report Id 304 852022-01-21 07:22:19.805 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Fetching Scan data for Id 1000207 862022-01-21 07:22:19.820 INFO 11 --- [ main] c.c.s.s.CxService [blKXd4Ey] : Fetching custom fields from project ID 67 872022-01-21 07:22:19.908 INFO 11 --- [ main] c.c.f.s.ResultsService [blKXd4Ey] : Issue tracking is custom bean implementation 882022-01-21 07:22:19.923 INFO 11 --- [ main] c.c.f.c.GitLabIssueTracker [blKXd4Ey] : Initializing GitLab processing 892022-01-21 07:22:20.325 INFO 11 --- [ main] c.c.f.s.CodeBashingService [blKXd4Ey] : not using CodeBashing lessons integration - one or more of the mandatory properties is missing 902022-01-21 07:22:20.325 INFO 11 --- [ main] c.c.f.s.IssueService [blKXd4Ey] : Processing Issues with custom bean GitLab 912022-01-21 07:22:20.325 INFO 11 --- [ main] c.c.f.c.GitLabIssueTracker [blKXd4Ey] : Executing getIssues GitLab API call 922022-01-21 07:22:20.465 INFO 11 --- [ main] c.c.f.s.IssueService [blKXd4Ey] : Issue still exists. Updating issue with key CX Second_Order_SQL_Injection @ ***.cs [master] 932022-01-21 07:22:21.352 INFO 11 --- [ main] c.c.f.c.GitLabIssueTracker [blKXd4Ey] : Finalizing GitLab Processing 942022-01-21 07:22:21.352 INFO 11 --- [ main] c.c.f.s.ResultsService [blKXd4Ey] : ####Checkmarx Scan Results Summary#### 952022-01-21 07:22:21.352 INFO 11 --- [ main] c.c.f.s.ResultsService [blKXd4Ey] : Team: /CxServer/TEAM***, Project: *********, Scan-Id: 1000207 962022-01-21 07:22:21.353 INFO 11 --- [ main] c.c.f.s.ResultsService [blKXd4Ey] : The vulnerabilities found for the scan are: high: 2, medium: 21, low: 156, info: 0 972022-01-21 07:22:21.353 INFO 11 --- [ main] c.c.f.s.ResultsService [blKXd4Ey] : To view results use following link: https://***.com/CxWebClient/ViewerMain.aspx?scanid=1000207&projectid=67 982022-01-21 07:22:21.353 INFO 11 --- [ main] c.c.f.s.ResultsService [blKXd4Ey] : ###################################### 992022-01-21 07:22:21.353 INFO 11 --- [ main] c.c.f.s.ThresholdValidatorImpl [blKXd4Ey] : Checking Thresholds exists. sast thresholds: false. sca thresholds: false 1002022-01-21 07:22:21.353 INFO 11 --- [ main] c.c.f.CxFlowRunner [blKXd4Ey] : Build succeeded. all checks passed 1012022-01-21 07:22:21.353 INFO 11 --- [ main] c.c.f.CxFlowRunner [blKXd4Ey] : Completed Successfully 1022022-01-21 07:22:21.354 INFO 11 --- [ main] c.c.f.CxFlowRunner [blKXd4Ey] : Finished with exit code: 0 1032022-01-21 07:22:21.359 INFO 11 --- [extShutdownHook] o.s.s.c.ThreadPoolTaskExecutor [] : Shutting down ExecutorService 'webHook' 1042022-01-21 07:22:21.362 INFO 11 --- [extShutdownHook] o.s.s.c.ThreadPoolTaskExecutor [] : Shutting down ExecutorService 'scanRequest' 105Cleaning up project directory and file based variables 10600:05 107Job succeeded
-
During the Checkmarx analysis, you can check the status from its GUI, it takes a long time to analyze.
-
After the analysis, you can check the result in Checkmarx or GitLab.
Troubleshooting
- If you find Checkmarx cannot find your team, please make sure to use English only in CX_TEAM, if you use non-English (ex: Chinese or Japanese), you can check the log and find it cannot find the team.
12022-01-12 02:51:22.748 INFO 11 --- [main] c.c.s.s.CxService [x4DNMhOL] : Found team /CxServer/Team1 with ID 16
Reference
- You can reference the official document to do the integration: https://checkmarx.atlassian.net/wiki/spaces/SD/pages/1929937052/GitLab+Integration.
Conclusion
- After this integration, you just need to commit the code and see the result in GitLab. All flows are in GitLab now, you don't need to worry about Checkmarx.
- Checkmarx provides lots of integration, you can reference https://checkmarx.atlassian.net/wiki/spaces/SD/pages/1339162785/CxSAST+CxSCA+Plugins+and+Integrations.
What's next
- Try to integrate the scan result to SonarQube), you can reference https://dennys.github.io/en/doc/devops/gitlab-checkmarx-sonarqube-integration/.
Posts in this Series
- Run SonarQube on Linux Docker with Mono to scan .NET 4.8 Code
- GitLab SonarQube Integration with .NET
- Use Grafana to Manage SonarQube KPI
- Use Grafana to Manage GitLab CI/CD Pipelines
- Use GitLab to do .NET 4.8 CI/CD
- GitLab Checkmarx CI/CD Integration
- GitLab Checkmarx SonarQube Integration