Integrar ferramentas de segurança com GitLab

  • Versão de lançamento: Yokohama
  • Atualizado 30 de jan. de 2025
  • 3 min. de leitura
  • Configure a ferramenta de segurança para GitLab, que não é compatível com o sistema de base.

    Antes de Iniciar

    Função necessária: sn_devops.admin

    Procedimento

    1. Navegar até DevOps > Integrações > Integrações de ferramentas e abra o registro de integração da ferramenta de orquestração GitLab.
    2. Navegue até a lista relacionada Mapeamentos de capacidade de integração da ferramenta.
    3. Selecione Novoe insira os seguintes valores nos campos de formulário.
      Campo Valor
      Integração da ferramenta GitLab
      Capacidade do tipo de ferramenta Segurança
      Formulário de mapeamento de capacidade de integração da ferramenta para GitLab
    4. Selecione Enviar.
    5. Navegue até a lista relacionada Capacidades de integração e selecione Novo.
    6. Insira os seguintes valores nos campos de formulário.
      Campo Valor
      Integração da ferramenta GitLab
      Mapeamento da capacidade Registro de mapeamento de capacidade criado na etapa 4.
      Ação Notificação
      Nota:
      Não edite registros de ação da ferramenta.
      Ativo Selecionado
      Tempos limites (ms) Tempo limite para o subfluxo correspondente. Se a execução do subfluxo exceder esse valor, ocorrerá uma exceção de tempo limite. O valor está em milissegundos (ms). O padrão é 45.000 (45 segundos).
      Nome do subfluxo sn_devops_vul_ints.devops_security_notification
      Domínio global
      Formulário de capacidade de integração para GitLab
      Nota:
      Desative a regra de negócio BR Seeded tool integrations not editable para integrar as ferramentas de segurança ao GitLab.
    7. Modifique a inclusão de script sn_devops_ints.DevOpsGitLabIntegrationHandler navegando até Definições do sistema > Inclusão de scripte pesquisando o script DevOpsGitLabIntegrationHandler.
      1. Modifique o método handleEvent para processar os resultados da verificação de segurança do pipeline do GitLab. Certifique-se de que o nome da fase de segurança no pipeline do GitLab seja igual ao nome atualizado nas variáveis VERACODE_STAGE_NAME, CMARX_ONE_STAGE_NAME ou CMARX_SAST_STAGE_NAME no método handleEvent. Substitua o código do método handleEvent pelo snippet de código a seguir.
         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");
            }
        },

        Nos exemplos a seguir, o pipeline do GitLab mostra que o nome da fase de segurança é o mesmo que as variáveis VERACODE_STAGE_NAME, CMARX_ONE_STAGE_NAME ou CMARX_SAST_STAGE_NAME, respectivamente, no método handleEvent.

        VERACODE_STAGE_NAME é para 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 é para 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 é para 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. Adicione o método getPipelineWithSecurityEventPayload ao script DevOpsGitLabIntegrationHandler.
        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;
            },