Configurando um pipeline básico: Gitlab
Tags: veracode, gitlab, ptbr, devops
Published: 2023-01-04 14:12:39

**Antes de começarmos**
Para fazer uma integração Veracode precisamos ter uma conta e nela obter as credenciais que vamos utilizar para autenticar as ferramentas, pode saber como obtê-las [aqui](https://dev.to/m3corp/credenciais-da-veracode-340m).

Como padrão para as implementações, vamos seguir um fluxo simples e montar os pipelines em imagens Linux. É perfeitamente possível utilizar imagens Windows, desde que se alterem os comandos para funcionar no Powershell. Como as ferramentas que vamos usar são construídas em Java, precisamos ter ele disponível no sistema.

**Desenho do pipeline**
A ideia é criar um modelo simples de validação de segurança, que consiga fazer uma combinação das soluções da Veracode para conseguir validar o código próprio e de terceiros, ter os resultados no LOG do pipeline e dentro da plataforma, para poder ser integrado com ferramentas de gerenciamento como Azure Boards e Jira. 

Considerando que o fluxo normal de um pipeline seja:
1. Fazer o checkout
2. Compilar e/ou carregar dependências
3. Publicar o artefato

Vamos adicionar as etapas da Veracode, de forma a nesse fluxo conseguirmos validar o código. É possível fazer alguns paralelismos e otimizações, mas a ideia aqui é mostrar uma forma bem simples de implementação. 

As etapas podem ou não serem usadas para quebrar o pipeline, isso vai depender da estratégia de implementação e das políticas aplicadas. Nesse exemplo, apenas a etapa do Pipeline Scan vai ser um definidor de quebra, verificando se existem falhas em código próprio e quebrando o fluxo caso encontre alguma. 

Nosso desenho então vai ficar:
1. Fazer o checkout
2. Compilar e/ou carregar dependências
3. Envia o código para ser analisado em segundo plano na plataforma da Veracode
4. Verifica os componentes de terceiros utilizados
5. Utiliza o Pipeline Scan para validar código próprio e definir quebra
6. Publicar o artefato

Como estamos pensando em uma imagem Linux, vamos utilizar comandos Shell para fazer o download das ferramentas, prepará-las e então utilizadas. A etapa do deploy em si não estará no código de exemplo. 

Para o exemplo, vamos utilizar um projeto Java com falhas conhecidas, chamado [Verademo](https://github.com/IGDEXE/Verademo). É sempre recomendado consultar o [guia de empacotamento](https://docs.veracode.com/r/c_comp_quickref) para saber o que precisa enviar para a Veracode analisar. 

**Construindo nosso Pipeline**
Para as credenciais, vamos precisar configurar variáveis conforme as opções do Gitlab, recomendo consultar a [documentação](https://docs.gitlab.com/ee/ci/variables/) para criar um grupo de variaveis com as credenciais, assim pode usar um mesmo usuário integrador para todas as esteiras.

Para definir o nome do projeto e o caminho do arquivo que vamos analisar, não vejo problemas em ter os valores definidos no arquivo de configuração, que ficaria dessa forma:
```
variables:
    APP_Profile: "GitLab.${CI_PROJECT_NAME}"
    Caminho_Arquivo: "target/verademo.war"
```

Com as nossas variáveis devidamente atualizadas, podemos fazer a criação dos stages conforme nosso desenho. Vou explicar como vamos fazer as etapas da Veracode, mas no final do artigo vai encontrar o script completo incluindo o checkout e o build. 

Nossa primeira etapa Veracode é utilizar o Wrapper para enviar os dados para a nuvem e processar em segundo plano. Vamos fazer isso para conseguirmos verificar os resultados no portal da Veracode e integrar com as ferramentas de bugtracking. Para utilizar o Wrapper, primeiro fazemos o download dele e lodo em seguida o utilizamos passando os parâmetros: 
- vid e vkey -> Credenciais
- action uploadandscan -> É a ação responsável por fazer o SCA e o SAST
- appname -> Identificador do projeto dentro do portal da Veracode
- createprofile -> Utilizamos para configurar se queremos ou não a criação de novos perfis caso não existam
- version -> É o identificador do scan dentro de um projeto/perfil de aplicação
- filepath -> Caminho do arquivo que queremos analisar

Como número de versão, estou utilizando o número de build. 
Colocando isso em código, temos:
```
sast:
    image: veracode/api-wrapper-java
    stage: Veracode
    script:
        - java -jar /opt/veracode/api-wrapper.jar
          -action UploadAndScan
          -vid "${VeracodeID}"
          -vkey "${VeracodeKey}"
          -appname $APP_Profile
          -createprofile true
          -autoscan true
          -criticality VeryHigh
          -filepath $Caminho_Arquivo
          -version "${CI_JOB_ID}"
    dependencies:
        - packaging
```
Dentro do GitLab temos essa opção de utilizar uma imagem da Veracode para fazer o processo.


Depois do Wrapper, nosso próximo stage vai ser o do SCA. 
Ao contrário do anterior, não precisamos passar diretamente sua credencial, mas ele só vai funcionar caso o valor **SRCCLR_API_TOKEN** esteja como uma variável de ambiente e disponível para o stage. 
A implementação é bem simples, basicamente apenas um Curl para fazer o download de um script do site da Veracode e em seguida utilizamos parâmetros Shell para fazer o scan.
É importante que o SCA rode na mesma pasta onde fica o arquivo com as dependências, então caso tenha dúvidas, consulte a [documentação](https://docs.veracode.com/r/Using_Veracode_SCA_with_Programming_Languages):
```
sca:
        image: openjdk:8
        stage: Artifact
        when: always
        script:
            - curl -sSL 'https://download.sourceclear.com/ci.sh' | bash -s – scan --update-advisor
```
Para ele podemos utilizar uma imagem genérica que tenha o Java instalado. 

Nossa última etapa vai utilizar algo para descompactar um ZIP que vamos baixar do site da Veracode. No exemplo eu utilizo o UNZIP para isso, mas fique a vontade para fazer a sua maneira.
O Pipeline Scan vai funcionar de forma similar ao Wrapper, mas precisamos apenas passar as credenciais e o caminho do arquivo. Como o nosso objetivo é usar o LOG com detalhes, passo um parâmetro para trazer não só o que foi encontrado, mas dicas sobre como corrigir:
```
pipeline_scan:
        image: openjdk:8
        stage: Veracode
        dependencies:
        - packaging
        when: always
        script:
            - curl -O https://downloads.veracode.com/securityscan/pipeline-scan-LATEST.zip
            - unzip pipeline-scan-LATEST.zip pipeline-scan.jar
            - java -jar pipeline-scan.jar
                --veracode_api_id "${VeracodeID}"
                --veracode_api_key "${VeracodeKey}"
                --file "$Caminho_Arquivo"
                --issue_details true
```
Recomendo a leitura da [documentação](https://docs.veracode.com/r/r_pipeline_scan_commands) para ver quais outros parâmetros podem ser utilizados, como o para configurar quais níveis de falhas são permitidos, por padrão nosso pipeline vai quebrar caso seja encontrada uma falha de qualquer nível.

Considerando a forma de funcionamento do Gitlab, vamos agrupar os processos em dois grupos, o primeiro é o de Build onde geramos o artefato que vamos analisar e o segundo é o da análise de código da Veracode. Na etapa de build, vamos executar o SCA.
Nosso script completo vai ficar assim:
```
# Definição dos stages
stages:
    - Artifact
    - Veracode

variables:
    APP_Profile: "GitLab.${CI_PROJECT_NAME}"
    Caminho_Arquivo: "target/verademo.war"

# Cria o ZIP com os arquivos conforme a documentação da Veracode
packaging:
    image: maven:3.3.9-jdk-8
    stage: Artifact
    script:
        - mvn package
    artifacts:
        paths:
            - $Caminho_Arquivo

# Utiliza o SCA para fazer a análise de componentes de terceiros
sca:
        image: openjdk:8
        stage: Artifact
        when: always
        script:
            - curl -sSL 'https://download.sourceclear.com/ci.sh' | bash -s – scan --update-advisor

# Inicia a análise SAST por meio do Wrapper
sast:
    image: veracode/api-wrapper-java
    stage: Veracode
    script:
        - java -jar /opt/veracode/api-wrapper.jar
          -action UploadAndScan
          -vid "${VeracodeID}"
          -vkey "${VeracodeKey}"
          -appname $APP_Profile
          -createprofile true
          -autoscan true
          -criticality VeryHigh
          -filepath $Caminho_Arquivo
          -version "${CI_JOB_ID}"
    dependencies:
        - packaging

# Utiliza o Pipeline Scan para uma análise mais rápida e validar quebra por erros encontrados
pipeline_scan:
        image: openjdk:8
        stage: Veracode
        dependencies:
        - packaging
        when: always
        script:
            - curl -O https://downloads.veracode.com/securityscan/pipeline-scan-LATEST.zip
            - unzip pipeline-scan-LATEST.zip pipeline-scan.jar
            - java -jar pipeline-scan.jar
                --veracode_api_id "${VeracodeID}"
                --veracode_api_key "${VeracodeKey}"
                --file "$Caminho_Arquivo"
                --gl_issue_generation true
                --issue_details true
```

**Resultados**
Com esse desenho, a etapa do SCA e do Pipeline Scan vão colocar nos LOGs as informações sobre as falhas encontradas, a exibição vai variar conforme a interface esteja configurada e a ferramenta que esteja utilizando, mas pensando nos resultados, vamos ter para o SCA: 
![Log SCA](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v5xyrk79lx0chrrcfop6.png)

E para o Pipeline Scan:
![LOG Pipeline Scan](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzh0a87pdw470hgnrksj.png)

Com isso temos um pipeline simples, mas funcional, onde pode verificar a segurança de seu projeto. Recomendo que em conjunto adicione ferramentas de validação de qualidade de código e testes funcionais, para ter um ciclo de desenvolvimento ideal.