Lab 1.2: Utilizando linters e ferramenta de segurança
Analisando código com ruff
Agora que já temos um pacote Python pronto para ser distribuído, é fundamental adotar práticas de qualidade de código que garantam a legibilidade, consistência e segurança do seu código. Uma ferramenta poderosa para ajudar nesse processo é o Ruff.
Ruff
Ruff é um linter rápido e eficiente para Python. Ele foi projetado para ser altamente configurável e rápido, realizando verificações de estilo e erros de código. Ele é mais rápido que outros linters populares (como o pylint e flake8) devido ao seu design otimizado e ao uso de técnicas de compilação.
Benefícios do Ruff:
- Desempenho: O Ruff é significativamente mais rápido do que linters tradicionais como o - pylint e flake8.
- Facilidade de Uso: Requer pouca configuração e é fácil de integrar em seu fluxo de trabalho.
- Alta Configuração: Você pode configurar quais regras deseja aplicar, ou até mesmo desativar certas verificações.
- Compatibilidade: O Ruff oferece compatibilidade com diversas regras de linters populares, como flake8, black, isort, etc.
- Análise de Segurança: Além de verificar o estilo do código, ele também verifica problemas de segurança, como importações não utilizadas e práticas arriscadas.
Como Integrar o Ruff no Seu Pacote Python localmente?
1 - Instalando o Ruff o primeiro passo é instalar o Ruff no seu ambiente de desenvolvimento. Você pode instalá-lo com o pip:
pip install ruff
2 - Rodando o Ruff no Código: Para rodar o Ruff em um diretório (onde seu pacote Python está localizado, por exemplo), rode o seguinte comando:
ruff check .
Isso irá verificar todo o código no diretório atual e subdiretórios. O Ruff então irá mostrar qualquer problema encontrado, como problemas de formatação ou uso incorreto de importações. Como podemos ver abaixo:
O Ruff identificou 3 erros, onde:
- Na linha 14 do arquivo
csv_functionserro de indentação, em decorrência do avanço da doc string. - Na linha 16 do arquivo
csv_functionserro de indentação, em decorrência do avanço da doc string. - Na linha 6 do arquivo
email_functionserro gerado por estar usando uma classe sem o devidoimport.
Após corrigir esses erros, ao rodar novamente ruff check . todas as verificações finalizaram sem problemas.
Buscando vulnerabilidades de dependências com Snyk
O Snyk é uma ferramenta de segurança para desenvolvedores, focada principalmente em detectar e corrigir vulnerabilidades de segurança em dependências de código, infraestrutura e pipelines de CI/CD.
O Snyk ajuda a proteger as aplicações contra problemas de segurança que podem ser introduzidos por pacotes e bibliotecas externas, além de oferecer monitoramento contínuo da segurança.
Como o Snyk atua na segurança de dependências
Análise de Dependências
- O Snyk realiza a análise automática das dependências de um projeto. Ele escaneia tanto as dependências diretas (pacotes explicitamente incluídos no projeto) quanto as dependências transitivas (pacotes que essas dependências diretas exigem).
- Ao escanear o projeto, o Snyk identifica as bibliotecas e versões usadas, e compara essas versões com uma base de dados de vulnerabilidades conhecidas, que contém informações sobre falhas de segurança já documentadas em várias bibliotecas populares.
Identificação de Vulnerabilidades:
- Após realizar a análise, o Snyk identifica vulnerabilidades conhecidas nas dependências do projeto. Ele pode detectar problemas como:
- CVE (Common Vulnerabilities and Exposures): O Snyk utiliza bancos de dados de CVEs para identificar falhas já publicadas na segurança de software.
- Vulnerabilidades específicas de pacotes: O Snyk não se limita apenas a problemas CVE, ele também verifica por falhas específicas em pacotes e versões populares.
- O Snyk também considera vulnerabilidades em tempo de execução e problemas relacionados a permissões de pacotes, garantindo que não haja riscos durante a execução do software.
Recomendações de Correção:
- Para cada vulnerabilidade detectada, o Snyk fornece recomendações claras de como corrigi-las. Isso pode incluir:
- Atualizar para uma versão segura da dependência.
- Substituir uma dependência vulnerável por uma alternativa mais segura.
- Aplicar patches (em alguns casos, se disponível).
Integrando o Ruff no CI/CD
Agora, vamos configurar o Ruff para ser executado automaticamente em um pipeline de CI/CD. Vou exemplificar o processo usando o GitHub Actions, mas o conceito é semelhante em outras ferramentas de CI/CD.
1 - Criar o arquivo de configuração do GitHub Actions
Na raiz do seu repositório, crie o arquivo .github/workflows/ruff.yml com o seguinte conteúdo:
name: Lint with Ruff
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install ruff # Instala o Ruff
- name: Run Ruff Linting
run: ruff check .
Onde:
- on: Define os eventos que acionam o workflow. Neste caso, ele será executado em:
- push: Aciona o pipeline quando houver um push na branch main.
- pull_request: Aciona o pipeline quando houver um pull request para a branch main.
- jobs: Define os jobs do CI. O job lint será executado em um runner Ubuntu:
- steps: Cada etapa do job:
- Check out repository: Faz o checkout do código do repositório.
- Set up Python: Configura o ambiente Python com a versão 3.x.
- Install dependencies: Atualiza o pip e instala as dependências do projeto (definidas no requirements.txt), além de instalar o Ruff.
- Run Ruff Linting: Executa o Ruff para verificar todos os arquivos Python do projeto.
- steps: Cada etapa do job:
2 - Adicionar o arquivo de configuração ao repositório
Use os comandos do Git para adicionar esse arquivo ao repositório remoto:
git add .github/workflows/ruff.yml
git commit -m "Adiciona pipeline de linting com Ruff"
git push origin main
3 - Verificar a execução do pipeline
Após configurar o GitHub Actions, sempre que houver um push ou pull_request para a branch main, o GitHub acionará o pipeline e executará a análise de linting do Ruff, ela pode ser visualizada na aba Actions do repositório:
Se houver problemas no código, eles serão exibidos nos logs do pipeline como abaixo:
Mas, caso contrário retornará sucesso em todas as etapas:
Pre-commit
O Pre-commit é uma ferramenta que configura verificações de qualidade de código e vulnerabilidades antes de um commit ser feito e publicar um código no repositório. Sua vantagem consiste em configuração simplificada e mitigação de riscos ao apontar falhas e problemas no seu código antes mesmo dele ser publicado.
Abaixo, veja como configurar o Pre-commit e realizar as verificações de qualidade e segurança no código:
Pré-requisitos:
Para utilizar a ferramenta, é necessário ter:
- Git instalado no ambiente
- Uma conta no Github
- Recomendamos também a utilização de um projeto Python para inicializar um repositório Git e checar os recursos do pre-commit.
Projeto de exemplo
Você pode utilizar o projeto de exemplo que disponibilizamos clicando aqui
Setup do Pre-commit
Inicialmente, o Pre-commit pode ser instalado no seu ambiente como um pacote Python. Execute o comando abaixo no seu terminal:
Inicialize o git na pasta raíz do seu projeto:
git init
Configuração das verificações executadas no pre-commit:
Iremos indicar as verificações a serem feitas no código a partir de um arquivo chamado .pre-commit-config.yaml
Crie este arquivo na pasta-raíz de seu projeto, e em seguida, iremos configurar as seguintes verificações no arquivo:
- Checagem de espaços em branco desnecessários
- Checagem da ordem dos imports seguindo as práticas recomendadas do PEP
- Indicador de linhas de código fora do padrão de formatação Python
- Checagem de código vulnerável com bandit
O arquivo configurado ficará assim:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
- id: flake8
- repo: https://github.com/pycqa/bandit
rev: 1.7.7
hooks:
- id: bandit
args: [ "-ll" ]
files: .py$
Entendendo o arquivo .pre-commit-config.yaml
Este arquivo é a "receita" que o pre-commit utiliza para garantir que o seu código siga padrões de qualidade e segurança antes mesmo de ser enviado ao repositório (Git).
Aqui está o que cada parte faz:
1. pre-commit-hooks (Ferramentas de Limpeza Básica)
-
trailing-whitespace: Remove automaticamente espaços em branco inúteis no final das linhas de texto.
-
end-of-file-fixer: Garante que todos os arquivos terminem com uma linha vazia (padrão de sistemas Unix para evitar problemas de leitura de arquivos).
-
check-yaml: Verifica se a sintaxe de todos os arquivos .yaml ou .yml do projeto está correta.
2. isort (Organização de Importações)
- isort: Organiza os seus imports no Python de forma alfabética e separada por seções (bibliotecas padrão, bibliotecas de terceiros e módulos locais). Isso evita bagunça no topo do código.
3. flake8 (Guia de Estilo e Erros)
- flake8: É um linter que verifica se o seu código segue a PEP 8 (o manual de estilo do Python). Ele aponta variáveis não utilizadas, linhas muito longas e outros erros de formatação.
4. Bandit (Análise de Segurança)
Este é um ponto crítico para projetos profissionais e de IA:
-
bandit: Faz uma análise estática focada em segurança.
-
args: [ "-ll" ]: Configura o Bandit para reportar apenas problemas de nível de severidade Médio e Alto (ignorando os Baixos para evitar ruído).
-
files: .py$: Garante que o Bandit analise especificamente arquivos com extensão .py.
-
Por que isso é importante?
Ao rodar o git commit, o pre-commit executará todas essas ferramentas. Se o Bandit encontrar uma vulnerabilidade ou o Flake8 encontrar um erro de estilo, o commit será bloqueado, forçando você a corrigir o problema antes de seguir adiante.
Configurando o Ruff para rodar antes de um Commit (opcional)
Se você quiser garantir que o código seja verificado antes de ser comitado, pode usar uma ferramenta como pre-commit para integrar o Ruff diretamente ao processo de commit.
Aplicando verificações na prática com pre-commit:
Com o arquivo .pre-commit-config.yaml devidamente configurado, iremos testar e acompanhar as verificações retornadas pelo pre-commit:
Siga estes passos para instalar e ativar os hooks no seu repositório local.
Passo 1: Instalação da Ferramenta
Instale a ferramenta no seu ambiente virtual (é crucial instalá-la no seu venv ou conda).
# Garanta que seu ambiente virtual esteja ativo
pip install pre-commit
Passo 2: Configuração e Download dos Hooks
Certifique-se de que o arquivo .pre-commit-config.yaml (gerado acima) esteja na raiz do seu projeto.
Ao rodar este comando, o pre-commit lê o arquivo YAML e baixa todas as ferramentas (black, isort, etc.) para o ambiente de cache local:
pre-commit install
Você deve ver uma mensagem de sucesso como: pre-commit installed at .git/hooks/pre-commit.
Passo 3: Uso e Teste
O pre-commit agora está ativo. Não é necessário fazer mais nada; ele será acionado automaticamente em cada git commit.
- Faça uma alteração de teste: Deixe um
importfora de ordem ou insira um espaço em branco no final de uma linha. -
Adicione e Comite:
git add . git commit -m "feat: configurando pre-commit"
O que vai acontecer no commit?
- Se houver correção automática (Black/isort): O
pre-commitcorrigirá o arquivo e o commit falhará com uma mensagem dizendo:Files were modified by the hooks. Re-run commit..- Você deve rodar
git add .novamente (para incluir as correções) e, em seguida,git commitde novo.
- Você deve rodar
- Se houver erro de linting (Flake8): O commit falhará e você verá a linha exata do erro. Você deve corrigir o código manualmente



