Analisando projetos Flutter/Dart com Veracode
Tags: veracode, beginners, tutorial, security
Published: 2023-01-04 14:21:20

No final de 2022 a Veracode anunciou o suporte em suas soluções de análise de vulnerabilidades para projetos Flutter e Dart. O objetivo desse artigo é mostrar de uma forma rápida e direta, como é simples integrar Veracode não apenas para fazer a análise, como também automaticamente criar os Work Itens integrados com o Azure DevOps.

**Antes de começarmos**
Para exemplificar um fluxo automatizado, vamos utilizar o Azure DevOps Pipelines para fazer o processo de build e validar o projeto Android.
Antes de começarmos, precisamos de uma task para permitir a utilização do Flutter no pipeline, existem várias opções e eu escolhi a que tinha mais downloads, no caso essa [aqui](https://marketplace.visualstudio.com/items?itemName=Hey24sheep.flutter). 
Caso opte por outra task ou outra forma de configurar o Flutter, as etapas nesse tutorial relacionadas ao processo de build vão mudar, mas não a relacionada a Veracode. 
Como projeto de testes, escolhi um com falhas conhecidas de um projeto educacional, que pode ser [clonado aqui](https://github.com/IGDEXE/secDevLabs/tree/master/owasp-top10-2016-mobile/m5/panda_zap). 

**Configurando Veracode**
Fora as task relacionadas ao Flutter, vamos usar o [conjunto de tasks](https://dev.to/m3corp/veracode-utilizando-os-plug-ins-no-azure-devops-531i) da Veracode e as [credenciais](https://dev.to/m3corp/configurando-o-arquivo-de-credenciais-3c0k), recomendo a leitura desses artigos linkados para saber como obter esses requisitos. 

**Desenho do Pipeline**
Nosso fluxo vai seguir a ideia de:
1. Configuração do Flutter
2. Build conforme o guia de empacotamento
3. Validação do binário com Veracode

Para esse exemplo vamos utilizar uma imagem de Ubuntu e fazer o checkout na master/main. Como primeiro passo, vamos configurar o Flutter:
```
trigger:
- master

pool:
  vmImage: ubuntu-latest

steps:
- task: FlutterInstall@0
  inputs:
    mode: 'auto'
    channel: 'stable'
    version: 'latest'
```
Estamos utilizando as opções padrões da task que importamos, pegando a versão mais recente.

As análises da Veracode são feitas com base no binário, já que fazendo isso ela consegue ter certeza que todos os tipos de falhas possíveis para uma análise SAST vão poder ser localizadas na análise, garantindo a baixa taxa de falsos positivos da Veracode. 
Para fazer a compilação, vamos ativar a opção de Debug, isso vai ajudar o processo de análise a conseguir apontar exatamente onde estão as falhas, conforme a orientação no [guia de empacotamento](https://docs.veracode.com/r/Dart_and_Flutter_Application_Packaging):
```
- task: FlutterBuild@0
  inputs:
    target: 'apk'
    projectDirectory: 'owasp-top10-2016-mobile/m5/panda_zap/mobile/lib'
    debugMode: true
    extraArgs: '--ignore-deprecation'
```
O diretório do projeto foi alterado, conforme a orientação que encontramos no repositório, já que na verdade ele é um conjunto de diversos exemplos em diversas linguagens. Como é um projeto feito em versões mais antigas, passamos um argumento extra para ignorar isso e fazer a compilação. 

Para a etapa da Veracode, antes vamos criar duas variáveis, sendo uma para o nome do projeto e outra para o caminho do binário que vamos analisar:
```
variables:
  veracodeAppProfile: $(Build.DefinitionName)
  caminhoPacote: owasp-top10-2016-mobile/m5/panda_zap/mobile/build/app/outputs/flutter-apk/app-debug.apk
```
Para o nome vamos dinamicamente pegar o nome do pipeline, enquanto para versão estamos usando o caminho padrão do APK gerado. 

Agora falando da etapa da Veracode, vamos primeiro configurar a task **Veracode Upload and Scan** usando uma [Service Connection](https://dev.to/m3corp/como-criar-uma-service-connetion-1ljp) para as credenciais. 
Os parâmetros que precisamos configurar são:

- Application Name -> Vamos usar a variável veracodeAppProfile
- Scan Name -> Apontamos a variável que pega o valor do número de build, mas pode sincronizar com a versão do projeto
- Filepath -> Usamos a variável caminhoPacote

Fora isso, na seção **Advanced Scan Settings** vamos marcar a opção **Create Application Profile** e em **Veracode Scan Results** marcamos a **Import Results upon Scan Completion**.

Com isso nossa task vai fazer o scan e armazenar os resultados num perfil de aplicação que tenha o nome do pipeline, salvando cada scan com o número de execução e aguardando que a analise seja completada para seguir o fluxo. Em YAML fica assim:
```
- task: Veracode@3
  inputs:
    ConnectionDetailsSelection: 'Endpoint'
    AnalysisService: 'Veracode'
    veracodeAppProfile: '$(veracodeAppProfile)'
    version: '$(build.buildNumber)'
    filepath: '$(caminhoPacote)'
    createProfile: true
    importResults: true
    maximumWaitTime: '360'
```

**Recebendo os resultados**
Para finalizar, vamos utilizar a segunda task da Veracode para importar as falhas que foram encontradas para o Azure Boards. 

Na **Veracode Flaw Importer** vamos passar a variável veracodeAppProfile no campo **Application Name**, utilizando a mesma Service Connection que na task anterior. Em **Work Item Settings** vamos colocar para importar todos os tipos de falhas, de todos os tipos de scan e registrar elas como Bugs no Boards relacionado a mesma área do projeto que o pipeline está armazenado. Adicionamos como Tags, o nome do scan e CWE.
Em YAML vai ficar assim:
```
- task: Veracode Flaw Importer@3
  inputs:
    ConnectionDetailsSelection: 'Endpoint'
    AnalysisService: 'Veracode'
    veracodeAppProfile: '$(veracodeAppProfile)'
    sandboxName: 
    scanType: 'Dynamic, Static, and Software Composition Analysis'
    importType: 'All Flaws'
    workItemType: 'Bug'
    area: '$(system.teamProject)'
    overwriteAreaPathInWorkItemsOnImport: true
    flawImportLimit: '1000'
```

Com isso temos um pipeline simples, que consegue gerar um APK e validar a segurança desse projeto. Vale reforçar que embora tenhamos feito esse exemplo no Azure DevOps, a análise pode ser feita e integrada em qualquer ferramenta de CI/CD suportada pela Veracode, pode consultar diversos exemplos de implementação em nosso [GitHub](https://github.com/M3Corp-Community/Veracode). 

Unindo todas as etapas, nosso pipeline vai ficar assim:

```
# Exemplo de pipeline para Flutter/Dart

trigger:
- master

pool:
  vmImage: ubuntu-latest

variables:
  veracodeAppProfile: $(Build.DefinitionName)
  caminhoPacote: owasp-top10-2016-mobile/m5/panda_zap/mobile/build/app/outputs/flutter-apk/app-debug.apk

steps:
- task: FlutterInstall@0
  inputs:
    mode: 'auto'
    channel: 'stable'
    version: 'latest'

- task: FlutterBuild@0
  inputs:
    target: 'apk'
    projectDirectory: 'owasp-top10-2016-mobile/m5/panda_zap/mobile/lib'
    debugMode: true
    extraArgs: '--ignore-deprecation'

- task: Veracode@3
  inputs:
    ConnectionDetailsSelection: 'Endpoint'
    AnalysisService: 'Veracode'
    veracodeAppProfile: '$(veracodeAppProfile)'
    version: '$(build.buildNumber)'
    filepath: '$(caminhoPacote)'
    createProfile: true
    importResults: true
    maximumWaitTime: '360'

- task: Veracode Flaw Importer@3
  inputs:
    ConnectionDetailsSelection: 'Endpoint'
    AnalysisService: 'Veracode'
    veracodeAppProfile: '$(veracodeAppProfile)'
    sandboxName: 
    scanType: 'Dynamic, Static, and Software Composition Analysis'
    importType: 'All Flaws'
    workItemType: 'Bug'
    area: '$(system.teamProject)'
    overwriteAreaPathInWorkItemsOnImport: true
    flawImportLimit: '1000'
```

Podemos configurar as tasks da Veracode para funcionar como um definidor de quebra de fluxo, conforme políticas definidas na plataforma. Para saber como fazer esse e outros tipos de configurações, por favor consulte a [documentação oficial](https://docs.veracode.com/) ou nosso [blog técnico](https://dev.to/m3corp).