Chega de copiar YAML de segurança: Camada AppSec para projetos Java via Gradle Convention Plugin

Chega de copiar YAML de segurança: Camada AppSec para projetos Java via Gradle Convention Plugin

Este artigo explora como padronizar e centralizar as verificações de segurança em projetos Java, movendo a lógica de scripts CI/CD dispersos para um plugin Gradle reutilizável. O objetivo é simplificar o fluxo de trabalho de desenvolvimento e garantir artefatos de segurança consistentes.

MundiX News·13 de maio de 2026·10 min de leitura·👁 5 views

A maior dificuldade na segurança de aplicações Java (AppSec) raramente reside em encontrar mais um scanner. As equipes geralmente já possuem um conjunto de ferramentas, como SonarQube para análise de código, OWASP Dependency-Check para verificação de dependências, CycloneDX para SBOM (Software Bill of Materials), e ferramentas de cobertura como JaCoCo ou Kover. Além disso, plataformas de CI/CD como GitLab CI, Jenkins, TeamCity ou GitHub Actions são amplamente utilizadas para orquestrar essas verificações.

No entanto, o processo tende a se fragmentar com o tempo. Um serviço pode gerar relatórios do Dependency-Check em um diretório, enquanto outro gera apenas HTML. Um pode integrar corretamente os metadados de merge request ao SonarQube, enquanto outro os trata como análise de branch regular. Um projeto pode gerar SBOM apenas para dependências de runtime, enquanto outro inclui dependências de teste, resultando em relatórios ruidosos. Em projetos multi-módulo, exceções surgem, e pedaços de YAML são copiados de repositórios vizinhos, modificados superficialmente, e assim continuam. Inicialmente, isso pode não parecer um problema, mas em poucos meses, o processo de build de segurança sofre um desvio considerável. Foi para resolver essa questão que o autor desenvolveu o secure-build-gradle-plugin, não como um novo scanner, mas como uma camada de build tooling que padroniza a integração das ferramentas de AppSec existentes em projetos Gradle.

A abordagem convencional para DevSecOps frequentemente começa com arquivos YAML de CI/CD. Para um único serviço Java, um script como este é compreensível:

yaml
script:
  - ./gradlew test
  - ./gradlew dependencyCheckAnalyze
  - ./gradlew cyclonedxBom
  - ./gradlew sonar

Isso é claro, as etapas são visíveis, o pipeline é executado e os relatórios são gerados. O problema surge quando essa abordagem é replicada em dezenas de serviços. Cada serviço gradualmente se torna responsável por sua própria integração de segurança. As equipes copiam trechos de pipelines antigos, as versões de plugins e scanners divergem, os caminhos dos relatórios se tornam inconsistentes. Alguns adicionam SARIF, outros esquecem. Alguns configuram o SonarQube para receber XML de cobertura, outros não. Alguns usam análise de branch, outros análise de pull request. Onde antes era possível replicar a verificação localmente, agora é preciso apenas fazer o push e esperar o pipeline. Externamente, isso pode parecer automação, mas na prática, transforma-se em um conjunto de integrações manuais ligeiramente diferentes. O mais frustrante é que as equipes começam a discutir não sobre riscos, mas sobre a configuração das ferramentas: "Por que o relatório não está aqui?", "Por que o SonarQube não vê a cobertura?", "Por que o Dependency-Check falha em um serviço, mas apenas gera um relatório em outro?", "Por que o projeto multi-módulo é especial novamente?". Nesse ponto, o problema não é a falta de ferramentas, mas a ausência de um local centralizado para convenções.

Manter toda a lógica de segurança apenas no CI/CD é inconveniente. O CI/CD é excelente como um ambiente de execução geral, fornecendo runners limpos, logs, artefatos, gates e um trilho de auditoria comum. No entanto, não é o local ideal para residir toda a lógica de verificação de segurança. Se toda a lógica estiver apenas em .gitlab-ci.yml ou Jenkinsfile, o desenvolvimento local torna-se secundário. O desenvolvedor faz o push do código não apenas para abrir um merge request, mas também para entender o que o pipeline de segurança pensa. Este é um loop de feedback ruim. Idealmente, o desenvolvedor deveria ser capaz de executar a mesma verificação básica antes do merge request, por exemplo, com ./gradlew clean securityAnalyze --no-daemon. O CI/CD, por sua vez, deveria executar o mesmo workflow e coletar artefatos previsíveis. Ou seja, o CI/CD deve executar o workflow de segurança, e não descrevê-lo novamente em cada repositório. Essa é uma distinção importante.

A ideia por trás da solução é simples: o comportamento de segurança deve residir mais perto do código, e o CI/CD deve executar o mesmo comportamento sem reimplementação. Para Gradle, isso se encaixa naturalmente em um plugin de convenção. O Gradle já é o local onde o projeto descreve como ele é construído, testado, publicado e quais tarefas estão disponíveis. Portanto, as convenções repetíveis de AppSec também podem ser colocadas lá. Não a política da empresa, não a aceitação final de risco, não o gerenciamento de vulnerabilidades, mas sim a camada de tempo de build: como executar o Dependency-Check, onde armazenar relatórios, quais formatos gerar, como criar SBOM, como passar cobertura para o SonarQube, como diferenciar análise de branch e merge request, como lidar com projetos multi-módulo e como fornecer um comando claro para o desenvolvedor.

O plugin é aplicado uma vez no projeto:

gradle
plugins {
  id "java"
  id "io.github.niki1337.securebuild.gradle-java" version "0.1.0"
}

Em seguida, o arquivo build.gradle contém apenas os valores específicos do serviço:

gradle
securityConventions {
  serviceName = "payment-api"
  sonarProjectKey = "payment-api"
  allowLocalSonar = false
}

Para um projeto multi-módulo, o plugin é geralmente aplicado no nível raiz:

gradle
plugins {
  id "io.github.niki1337.securebuild.gradle-java" version "0.1.0"
}

securityConventions {
  serviceName = "payments-platform"
  sonarProjectKey = "payments-platform"
  includedModules = ["api", "service"]
  excludedModules = ["test-fixtures"]
}

Após isso, o modelo de propriedade muda. O CI/CD ainda executa as verificações, a segurança ainda é responsável pelos requisitos e triagem, e os desenvolvedores ainda corrigem os achados. No entanto, a configuração repetível do scanner reside no sistema de build, em vez de ser copiada de repositório para repositório como um conhecimento tácito.

Por baixo dos panos, o plugin não substitui as ferramentas existentes. Ele as integra e padroniza: análise SonarQube, OWASP Dependency-Check, CycloneDX SBOM, cobertura JaCoCo ou Kover, comportamento Gradle single-module e multi-module, metadados Git branch e metadados GitLab merge request. O comando principal para o desenvolvedor é ./gradlew clean securityAnalyze --no-daemon. securityAnalyze torna-se o ponto de entrada normal para a verificação AppSec local, podendo executar testes, cobertura, geração de SBOM e análise de dependências. Se for necessário analisar partes individuais, as tarefas subjacentes não são ocultadas: ./gradlew cyclonedxDirectBom --no-daemon, ./gradlew dependencyCheckAnalyze --no-daemon, ./gradlew sonarHelp --no-daemon. Para multi-módulo: ./gradlew dependencyCheckAggregate --no-daemon. O objetivo não é ocultar as ferramentas, mas tornar o caminho normal óbvio.

Poder-se-ia argumentar: "Por que um plugin? Não podemos simplesmente escrever um .gitlab-ci.yml normal?". Sim, é possível, e para um único repositório, isso geralmente é suficiente. Mas em escala, os problemas usuais começam a surgir: caminhos de relatório divergentes, configurações de scanner divergentes, metadados SonarQube esquecidos, execução local diferente do pipeline, projetos multi-módulo exigindo soluções improvisadas, novos serviços copiando boilerplate antigo, a equipe de segurança recebendo formatos de artefato diferentes, e desenvolvedores sem entender qual comando executar antes do MR. Um plugin Gradle de convenção fornece um local versionado para essa lógica. O CI/CD permanece importante, mas torna-se uma camada de execução: o GitLab CI/Jenkins executa ./gradlew securityAnalyze, coleta artefatos e aplica gates. Enquanto o comportamento de build reside mais perto do projeto: o plugin Gradle conhece as tarefas, os caminhos de relatório, a estrutura multi-módulo e as convenções de metadados SonarQube. Isso é particularmente útil em ambientes fechados, onde muitas empresas da CEI não podem simplesmente usar SaaS e integrá-lo facilmente pela documentação. Existem GitLab internos, Nexus próprio, Harbor, SonarQube auto-hospedado, proxies, CAs internas, restrições de internet e runners separados. Nesse ambiente, a previsibilidade é mais importante do que uma bela imagem na documentação.

O SonarQube pode ser configurado "quase corretamente" com facilidade, o que é uma zona perigosa. O pipeline fica verde, a análise é enviada, algo aparece na UI. Mas os binários Java não foram passados, o XML de cobertura não foi transmitido, os metadados de merge request não foram enviados. O resultado parece existir, mas é mais fraco do que deveria ser. O plugin resolve essa rotina de forma centralizada. Ele lê configurações de variáveis de ambiente, propriedades Gradle ou securityConventions:

bash
export SONAR_HOST_URL="https://sonarqube.example.com"
export SONAR_PROJECT_KEY="payment-api"
export SONAR_TOKEN="token-value"

E prepara propriedades típicas do SonarQube para Java:

properties
sonar.sources
sonar.tests
sonar.java.binaries
sonar.java.test.binaries
sonar.java.libraries
sonar.java.test.libraries
sonar.coverage.jacoco.xmlReportPaths
sonar.exclusions
sonar.test.exclusions
sonar.cpd.exclusions
sonar.coverage.exclusions

Para pipelines de merge request do GitLab, ele pode mapear variáveis de CI:

CI_MERGE_REQUEST_IID                  -> sonar.pullrequest.key
CI_MERGE_REQUEST_SOURCE_BRANCH_NAME   -> sonar.pullrequest.branch
CI_MERGE_REQUEST_TARGET_BRANCH_NAME   -> sonar.pullrequest.base

Para pipelines de branch, metadados de análise de branch são definidos. Este é um trabalho tedioso, mas importante, e é exatamente o tipo de trabalho que deve ser resolvido uma vez.

O Dependency-Check é útil quando seus relatórios são previsíveis. Não se quer que um serviço gere JSON, outro apenas HTML, um terceiro SARIF em um diretório obscuro, e um quarto armazene tudo em um caminho customizado. O plugin padroniza os formatos: HTML, JSON, SARIF, XML e os grava em build/reports/dependency-check. Por padrão, analisadores de rede que podem tornar o pipeline instável em infraestrutura fechada são desativados: OSS Index, RetireJS, Node audit, Node package analyzer, suppressions hospedados, analisador KEV da CISA. No mundo ideal, todos teriam internet rápida e acesso às fontes externas necessárias. No mundo real corporativo, frequentemente há proxies, firewalls, mirrors, registros internos e proibição de saída direta. Portanto, o build de segurança não deve se tornar acidentalmente lento ou instável devido a um endpoint externo. Se houver um mirror interno, ele pode ser usado:

bash
DT_API_URL=https://dependency-track.example.com \
./gradlew dependencyCheckAnalyze --no-daemon

Por padrão, o build não falha por CVSS:

failBuildOnCVSS = 11

Como o CVSS máximo é 10, isso significa que o relatório é gerado, mas o build não é derrubado apenas pelo score. Esta é uma escolha consciente. Na primeira etapa, a equipe geralmente precisa de visibilidade e triagem. Se gates rígidos forem ativados imediatamente em dados ruidosos, os desenvolvedores rapidamente começarão a ver a segurança como um bloqueador sem sentido. Primeiro, dados, validação e redução de falsos positivos. Depois, políticas de bloqueio.

SBOM é útil apenas quando descreve um artefato útil. Se um projeto inclui dependências de teste e outro não, comparar os resultados é difícil. Se a raiz de um projeto multi-módulo é apenas um agregador, o SBOM de nível raiz pode descrever mal a aplicação real. O plugin foca em dependências de runtime e reduz o ruído desnecessário: dependências de runtime são incluídas, dependências de teste não são adicionadas, o texto da licença não é incorporado, o número de série pode ser desativado, e metadados desnecessários são reduzidos. Comandos típicos: ./gradlew cyclonedxDirectBom --no-daemon, ./gradlew cyclonedxBom --no-daemon. Relatórios: build/reports/cyclonedx, build/reports/cyclonedx-direct. Para projetos multi-módulo Spring Boot, o plugin tenta encontrar o módulo implantável, como um módulo com bootJar, e criar um SBOM mais próximo da aplicação real, em vez de um agregador raiz vazio. Isso parece um detalhe, até que você comece a enviar SBOMs para o Dependency-Track e a analisar por que metade dos achados se refere a algo que não entra em runtime.

A configuração de cobertura é necessária para análise normal do SonarQube, mas os caminhos frequentemente divergem. O plugin suporta JaCoCo e Kover. No modo auto, ele usa Kover se já estiver presente, caso contrário, conecta JaCoCo:

gradle
securityConventions {
  coverageProvider = "auto"
}

Para JaCoCo, o plugin usa JaCoCo 0.8.13, torna jacocoTestReport dependente de tests, inclui saída XML e passa o caminho XML para o SonarQube. O caminho típico é build/reports/jacoco/test/jacocoTestReport.xml. Novamente, isso não é ciência de foguetes, é apenas a configuração repetível que não se quer corrigir em cada serviço separadamente.

Projetos Gradle multi-módulo rapidamente revelam a maturidade da integração. Para um projeto single-module de demonstração, quase qualquer scanner parece bonito. E então vem o repositório real: root, api, service, domain, client, test-fixtures. E começa: onde está o source? Onde estão os tests? Onde estão os binários? Qual módulo é implantável? Quais módulos incluir na análise? O que fazer com a raiz? O plugin identifica subprojetos Java com java, java-library e suporta filtros:

gradle
securityConventions {
  includedModules = ["api", "service"]
  excludedModules = ["test-fixtures"]
}

No modo multi-módulo, ele configura a cobertura por módulos Java, coleta caminhos de XML de cobertura, configura a análise SonarQube de nível raiz, define caminhos de source/test/binary/library de nível de módulo, executa a agregação do Dependency-Check, tenta não gerar um SBOM de nível raiz ruidoso, usa o módulo implantável para SBOM quando possível, e mantém um securityAnalyze unificado de nível raiz. Essa é a diferença entre "nós conectamos um scanner" e "temos uma convenção de build para repositórios Java reais".

Com isso, o CI/CD se torna mais simples. Um exemplo de GitLab CI:

yaml
security:gradle:
  image: eclipse-temurin:17
  stage: test
  variables:
    GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle"
  script:
    - ./gradlew clean securityAnalyze --no-daemon
  artifacts:
    when: always
    expire_in: 7 days
    paths:
      - build/reports/dependency-check/
      - build/reports/cyclonedx/
      - build/reports/cyclonedx-direct/
      - "**/build/reports/jacoco/"

sonarqube:gradle:
  image: eclipse-temurin:17
  stage: test
  script:
    - ./gradlew sonar --no-daemon
  rules:
    - if: '$SONAR_TOKEN'

A ideia importante é: o CI/CD chama tarefas de build, não reimplementa convenções de segurança. O pipeline se torna mais legível, os artefatos mais previsíveis e a execução local mais próxima do CI.

O que este plugin não tenta resolver é intencionalmente limitado. Ele não substitui SonarQube, OWASP Dependency-Check, CycloneDX, DefectDojo ou Dependency-Track, triagem manual de vulnerabilidades, aceitação de risco, secret scanning, DAST, container scanning, IaC scanning ou processo de aprovação de release. Não é "todo o DevSecOps em uma dependência". É uma camada de tempo de build para AppSec Java: SCA, SBOM, cobertura, metadados SonarQube, comportamento local e CI/CD, convenções de relatório. O secret scanning é conscientemente atribuído a uma camada anterior, antes do commit e push, pois envolve lógica e loop de feedback diferentes.

Em resumo, o secure-build-gradle-plugin não resolve o problema de "falta de scanners". Ele resolve o problema de "scanners conectados de forma diferente em todos os lugares". Em vez de cada serviço reinventar SonarQube, Dependency-Check, CycloneDX e a configuração de cobertura, o projeto recebe uma camada Gradle única: ./gradlew securityAnalyze. Os desenvolvedores obtêm feedback mais cedo, o CI/CD recebe artefatos previsíveis, a equipe de segurança obtém formatos de relatório mais estáveis, e projetos multi-módulo recebem um comportamento que entende a estrutura do repositório. E o mais importante: a ferramenta de segurança se torna parte do fluxo de trabalho normal de engenharia Java, em vez de um conjunto de scripts ao redor dele.

🛡️⚡

Pare de pesquisar. Comece a hackear.

O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.

Testar grátis por 7 dias →

Sem cartão para começar · Planos a partir de R$49/mês

📤 Compartilhar & Baixar

🧰 Ferramentas recomendadas

Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Com centenas de ferramentas pré-instaladas, a distribuição Kali Linux facilita o trabalho de os profissionais de segurança começarem a fazer testes de segurança rapidamente. No entanto, com mais de 600 ferramentas em seu arsenal, o Kali Linux também pode ser desafiador. A nova edição deste prático livro abrange as atualizações nas ferramentas e inclui uma melhor abordagem da análise forense e da engenharia reversa. Ric Messier, autor, não fica apenas no teste de segurança, mas também faz uma abordagem sobre a execução de análise forense, incluindo a análise em disco e na memória, assim como alguma análise básica de malware. • Explore as diversas ferramentas disponíveis no Kali Linux • Entenda o valor do teste de segurança e examine os tipos de teste disponíveis • Aprenda os aspectos básicos do pentest em todo o ciclo de vida do ataque • Instale o Kali Linux em vários sistemas, tanto físicos quanto virtuais • Descubra como usar diferentes ferramentas destinadas à segurança • Estruture um teste de segurança baseado nas ferramentas do Kali Linux • Estenda as ferramentas do Kali para criar técnicas de ataque avançadas • Use o Kali Linux para ajudar a criar relatórios quando o teste terminar “A abordagem concisa, clara e baseada na experiência adotada por Ric Messier para a introdução do Kali Linux e dos testes de cibersegurança é incomparável. Este livro é uma leitura excelente e acessível para iniciantes e um recurso valioso para qualquer pessoa.” —Alexander Arlt, Consultor sênior de segurança, Google

Ver na Amazon
Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Compatível com portas USB-C e USB-A, ideal para ampliar a conectividade de dispositivos como MacBook Pro e outros com portas USB-C. Inclui um adaptador USB-A extra, proporcionando uma conexão Ethernet estável e veloz de até 1 Gbps, perfeita para filmes, jogos online e videoconferências. Oferece três portas USB 3.0 com velocidades de transferência de até 5 Gbps, permitindo conectar mouse, teclado, discos rígidos e outros periféricos. Fabricado em alumínio durável, garantindo longa vida útil e resistência ao uso diário. Design compacto e leve, ideal para viagens de negócios e uso diário, facilitando o transporte e armazenamento. Funciona com Windows 10/8.1/8, Mac OS e Chrome OS, oferecendo versatilidade incomparável para diversas necessidades de conectividade. Assegura uma conectividade estável e rápida, perfeita para tarefas exigentes como transferência de dados, streaming e mais.

Ver na Amazon
Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs is a crash course on web API security testing that will prepare you to penetration-test APIs, reap high rewards on bug bounty programs, and make your own APIs more secure. You'll learn how REST and GraphQL APIs work in the wild and set up a streamlined API testing lab with Burp Suite and Postman. Then you'll master tools useful for reconnaissance, endpoint analysis, and fuzzing, such as Kiterunner and OWASP Amass. Next, you'll learn to perform common attacks, like those targeting an API's authentication mechanisms and the injection vulnerabilities commonly found in web applications. You'll also learn techniques for bypassing protections against these attacks. In the book's nine guided labs, which target intentionally vulnerable APIs, you'll practice: Enumerating APIs users and endpoints using fuzzing techniques Using Postman to discover an excessive data exposure vulnerability Performing a JSON Web Token attack against an API authentication process Combining multiple API attack techniques to perform a NoSQL injection Attacking a GraphQL API to uncover a broken object level authorization vulnerability

Ver oferta
Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Up-to-date strategies for thwarting the latest, most insidious network attacks This fully updated, industry-standard security resource shows, step by step, how to fortify computer networks by learning and applying effective ethical hacking techniques. Based on curricula developed by the authors at major security conferences and colleges, the book features actionable planning and analysis methods as well as practical steps for identifying and combating both targeted and opportunistic attacks. Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition clearly explains the enemy's devious weapons, skills, and tactics and offers field-tested remedies, case studies, and testing labs. You will get complete coverage of Internet of Things, mobile, and Cloud security along with penetration testing, malware analysis, and reverse engineering techniques. State-of-the-art malware, ransomware, and system exploits are thoroughly explained. Fully revised content includes 7 new chapters covering the latest threats Includes proof-of-concept code stored on the GitHub repository Authors train attendees at major security conferences, including RSA, Black Hat, Defcon, and B-Sides

Ver na Amazon
Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Proteção de privacidade aprimorada: protege o link de transmissão de dados para evitar roubo de informações, fornecendo proteção de segurança robusta que protege a privacidade do usuário durante transferências de arquivos e garante uma conexão segura para interações de dispositivos sem preocupações em vários ambientes Uso a longo prazo: a camada protetora resistente ao desgaste, combinada com um corpo de metal resistente, oferece gerenciamento de calor confiável e qualidade duradoura durante o uso diário Entrega eficiente de energia: a tecnologia de chip inteligente garante a identificação automática dos requisitos de energia, fornecendo carregamento eficiente alinhando-se com vários protocolos de carregamento rápido para maior conveniência Proteção contra sobrecarga: evitando riscos de sobrecarga, este bloqueador de dados USB protege a vida útil da bateria e garante um desempenho estável, mantendo um fluxo estável de energia para melhorar a longevidade do dispositivo de forma eficaz Prático de transportar: com atenção à portabilidade, este bloqueador de dados USB oferece um design compacto que é leve e fácil de transportar, melhorando a conveniência do usuário e operação eficiente

Ver na Amazon

📩 Newsletter MundiX

Receba novidades de cibersegurança + um checklist de pentest grátis. Sem spam.

Ao assinar você concorda em receber e-mails. Cancele quando quiser.