와 보안 도구 통합 GitLab

  • 릴리스 버전: Yokohama
  • 업데이트 날짜 2025년 01월 30일
  • 읽기11분
  • 기본 시스템에서 지원되지 않는 보안 도구를 GitLab 구성합니다.

    시작하기 전에

    필요한 역할: sn_devops.admin

    프로시저

    1. 다음으로 이동 DevOps > 통합 > 도구 통합 을 클릭하고 GitLab 오케스트레이션 도구 통합 기록을 엽니다.
    2. 도구 통합 역량 매핑 관련 목록으로 이동합니다.
    3. 새로 만들기를 선택하고 양식 필드에 다음 값을 입력합니다.
      필드
      도구 통합 GitLab
      도구 유형 역량 보안
      GitLab에 대한 도구 통합 역량 매핑 양식
    4. 제출을 선택합니다.
    5. 통합 기능 관련 목록으로 이동하여 새로 만들기를 선택합니다.
    6. 양식 필드에 다음 값을 입력합니다.
      필드
      도구 통합 GitLab
      역량 매핑 4단계에서 생성된 역량 매핑 기록입니다.
      동작 알림
      주:
      도구 작업 기록은 편집하지 마십시오.
      활성 선택됨
      시간 제한(ms) 해당 하위 플로우에 대한 시간 제한입니다. 하위 플로우의 실행이 이 값을 초과하면 시간 초과 예외가 발생합니다. 값은 밀리초(ms)입니다. 기본값은 45,000(45초)입니다.
      하위 플로우 이름 sn_devops_vul_ints.devops_security_notification
      도메인 전역
      GitLab용 통합 기능 양식
      주:
      비즈니스 규칙을 비활성화하여 BR Seeded tool integrations not editable 보안 도구를 GitLab과 통합합니다.
    7. sn_devops_ints.DevOpsGitLabIntegrationHandler 시스템 정의 > 스크립트 포함으로 이동하고 스크립트를 검색하여 스크립트 포함을 DevOpsGitLabIntegrationHandler 수정합니다.
      1. GitLab 파이프라인에서 보안 검사 결과를 처리하도록 handleEvent 메서드를 수정합니다. GitLab 파이프라인의 보안 단계 이름이 handleEvent 메서드의 VERACODE_STAGE_NAME, CMARX_ONE_STAGE_NAME 또는 CMARX_SAST_STAGE_NAME 변수에서 업데이트한 이름과 동일한지 확인합니다. handleEvent 메서드 코드를 다음 코드 조각으로 바꿉니다.
         handleEvent: function(eventGr) {
            try {
                var renameHandler = new sn_devops.DevOpsPipelineRenameHandler(this.refTable, this.appContext, this.relatedRecord);
                renameHandler.handlePipelineRename(eventGr);
                var payload = JSON.parse(eventGr.getValue("original_payload"));
                this._logger.debug("typeof payload >>" + typeof payload);
                if (!gs.nil(payload) && typeof payload === 'object') {
                    var status = this.getTaskExecutionStatus(payload);
                    this._logger.debug("Task Execution status -> " + status);
                    if (gs.nil(status))
                        this.updateInboundEvent(eventGr, {
                            processing_details: gs.getMessage('Task execution status [{0}] is not handled', payload.build_status),
                            state: sn_devops.DevOpsCommonConstants.INBOUND_EVENT_STATE_IGNORED
                        });
                    else {
                        // create fake start event for cancelled job
                        if (status == 'cancelled') {
                            this.createFakeEvent(eventGr, payload, 'running');
                        }
                        var normalizedObject = {};
                        normalizedObject.taskExecution = this.getTaskExecutionObject(eventGr, payload, status);
                        normalizedObject.orchestrationTask = this.getOrchestrationTaskObject(normalizedObject.taskExecution, payload);
                        normalizedObject.callback = this.getCallbackObject(normalizedObject.taskExecution, payload);
                        var devopsUtil = new sn_devops.DevOpsUtil(this.refTable, this.appContext, this.relatedRecord);
                        normalizedObject = devopsUtil.schemaValidationForTransformedPayload(normalizedObject);
                        var VERACODE_STAGE_NAME = 'SN_VERACODE';
                        var CMARX_ONE_STAGE_NAME = 'SN_CMARX_ONE_STAGE_NAME';
                        var CMARX_SAST_STAGE_NAME = 'SN_CMARX_SAST_STAGE_NAME';
                        if (!gs.nil(payload.build_stage) && 
                            (   
                                payload.build_stage == VERACODE_STAGE_NAME ||
                                payload.build_stage == CMARX_ONE_STAGE_NAME ||
                                payload.build_stage == CMARX_SAST_STAGE_NAME 
                            )
                            && this.isCompleted(normalizedObject.taskExecution)) {
                            var queryParams = sn_devops.DevOpsQueryParamsHelper.convertToSingular(JSON.parse(eventGr.getValue('query_params')));
                            if (gs.nil(normalizedObject.taskExecution.securityScan)) {
                                normalizedObject.taskExecution.securityScan = {
                                    securityScanSummaryCount: 0
                                };
                            }
                            normalizedObject.taskExecution.securityScan.securityScanSummaryCount += 1;
                        }
                        this._logger.debug("Normalized Object: " + JSON.stringify(normalizedObject));
                        return JSON.stringify(normalizedObject);
                    }
                } else
                    this.updateInboundEvent(eventGr, {
                        processing_details: gs.getMessage('Payload is missing or invalid'),
                        state: sn_devops.DevOpsCommonConstants.INBOUND_EVENT_STATE_ERROR
                    });
            } catch (error) {
                throw sn_devops.DevOpsErrorHelper.createDevOpsScriptIncludeError(error, sn_devops_ints.DevOpsIntegrationsCommonMessages.GITLAB_INBOUND_EVENT_PROCESS_ISSUE, "DevOpsGitLabIntegrationHandler.handleEvent", "handleEvent");
            }
        },

        다음 예에서 GitLab 파이프라인은 보안 단계 이름이 handleEvent 메서드의 VERACODE_STAGE_NAME, CMARX_ONE_STAGE_NAME 또는 CMARX_SAST_STAGE_NAME 변수와 각각 동일함을 보여줍니다.

        VERACODE_STAGE_NAME Veracode용입니다.
        image: maven:latest
        stages:
          - build
          - SN_VERACODE
          - Deploy
        
        build_1:
          stage: build
          tags:
            - local-runner1
          script:
            - echo "build"
            
        security_test:
          stage: SN_VERACODE
          tags:
            - local-runner1
          script:
            - |
              curl "https://<instance>.service-now.com/api/sn_devops/v1/devops/tool/security?toolId=<gitlab_tool_sys_id> " \
                --request POST \
                --header "Accept:application/json" \
                --header "Content-Type:application/json" \
                --data "{
                      \"pipelineInfo\": {
                        \"buildNumber\": \"${CI_JOB_ID}\",
                        \"taskExecutionUrl\": \"${CI_JOB_URL}/\"
                      },
                      \"securityResultAttributes\": {
                        \"scanner\": \"Veracode\",
                        \"applicationName\": \"Application\"
                      }
                    }" \
                --user 'devops.system':’password’
        
        

        CMARX_ONE_STAGE_NAME Checkmarx One용입니다.

        image: maven:latest
        stages:
          - build
          - SN_CMARX_ONE_STAGE_NAME
          - Deploy
        
        build_1:
          stage: build
          tags:
            - local-runner1
          script:
            - echo "build"
            
        security_test:
          stage: SN_CMARX_ONE_STAGE_NAME
          tags:
            - local-runner1
          script:
            - |
              curl "https://<instance>.service-now.com/api/sn_devops/v1/devops/tool/security?toolId=<gitlab_tool_sys_id> " \
                --request POST \
                --header "Accept:application/json" \
                --header "Content-Type:application/json" \
                --data "{
                      \"pipelineInfo\": {
                        \"buildNumber\": \"${CI_JOB_ID}\",
                        \"taskExecutionUrl\": \"${CI_JOB_URL}/\"
                      },
                      \"securityResultAttributes\": {
                        \"scanner\": \"Checkmarx One\",
                        \"projectId\": \"projectId\",
                        \"scanId\": \"scanId\",
                      }
                    }" \
                --user 'devops.system':’password’

        CMARX_SAST_STAGE_NAME Checkmarx SAST를 위한 것입니다.

        image: maven:latest
        stages:
          - build
          - SN_CMARX_SAST_STAGE_NAME
          - Deploy
        
        build_1:
          stage: build
          tags:
            - local-runner1
          script:
            - echo "build"
            
        security_test:
          stage: SN_CMARX_SAST_STAGE_NAME
          tags:
            - local-runner1
          script:
            - |
              curl "https://<instance>.service-now.com/api/sn_devops/v1/devops/tool/security?toolId=<gitlab_tool_sys_id> " \
                --request POST \
                --header "Accept:application/json" \
                --header "Content-Type:application/json" \
                --data "{
                      \"pipelineInfo\": {
                        \"buildNumber\": \"${CI_JOB_ID}\",
                        \"taskExecutionUrl\": \"${CI_JOB_URL}/\"
                      },
                      \"securityResultAttributes\": {
                        \"scanner\": \"Checkmarx\",
                        \"projectId\": \"projectId\"
                      }
                    }" \
                --user 'devops.system':’password’
      2. DevOpsGitLabIntegrationHandler 스크립트에 getPipelineWithSecurityEventPayload 메서드를 추가합니다.
        getPipelineWithSecurityEventPayload: function(payload) {
                var gr = new GlideRecordSecure('sn_devops_task_execution');
                gr.addEncodedQuery("execution_url=" + payload.pipelineInfo.taskExecutionUrl);
                gr.query();
                var task = null;
                if (gr.next()) {
                    task = gr;
                }
                if (gs.nil(task) || gs.nil(task.orchestration_task) || gs.nil(task.orchestration_task.step)) {
                    throw "Pipeline Info not found";
                }
                var step = task.orchestration_task.step.getRefRecord();
                var pipelineDAO = new sn_devops.DevOpsPipelineDAO();
                var query = 'sys_id=' + step.pipeline;
                var pipeline = pipelineDAO.getLimitedRecordsByEncodedQuery(query);
                return pipeline;
            },