1
Java seguro na prática:
Shift Left,
Zero Trust e
Trusted Software Supply Chain
no Azure Red Hat OpenShift
Link
rafabene@gmail.com
rafabene@gmail.com
apiVersion: redhat/v2
kind: Principal Software Engineer
metadata:
name: Rafael Benevides
namespace: Red Hat Inc.
annotations:
contributor: Opensource
labels:
developer: Java, Go
hobby: 4x4, drones, motos
spec:
replicas: 1
containers:
image: benevides/rafael:latest
Rafael Benevides
@rafabenedev
1 - Introdução
“Não importa se você é júnior ou sênior, se trabalha em fintech ou e-commerce: a segurança do código Java impacta negócios de bilhões.”
Quem lembra deste caso?
Impacto:
Imagina o que pode acontecer se …
Alguém explorar uma vulnerabilidade e tiver acesso a modificar (ou até mesmo ler dados sensíveis de milhares de clientes)
O papel do desenvolvedor - DevOps antigamente…
O papel do desenvolvedor hoje: Segurança não é só infra
Shift Left: Antecipando os problemas
Nossa jornada hoje
Shift
left
Código
inseguro
Zero
trust
ARO
2 - “Desenvolvimento seguro em Java: práticas de Shift Left”
Bancos sofrem ataques todos os dias e de todos os tipos
Top vulnerabilidades em bancos:
Injeções (SQL/LDAP/Command)
SQL Injection
Parece batido, mas uma simples concatenação de Strings e você está exposto!
String sql = "SELECT * FROM contas WHERE cpf='" + cpf + "'";
Solução:
@Query("SELECT c FROM Conta c WHERE c.cpf = :cpf")
Conta findByCpf(@Param("cpf") String cpf);
XSS - Cross-site scripting
Você vê algum problema nisso?��@WebServlet("/search")
public class SearchServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
String q = req.getParameter("q");
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().println("<html><body>Você procurou por: " + q + "</body></html>");
}
}
XSS - Cross-site scripting
Ou nisto?��document.getElementById("out").innerHTML = userInput;
XSS - Cross-site scripting
Problema: Se o que o usuário enviou contiver HTML/JS, ele será inserido no DOM e executado no navegador de quem acessar a página.
XSS - Cross-site scripting
Manipulando uma página "real" o atacante consegue dados sensíveis do usuário.��
XSS - Cross-site scripting
XSS - Cross-site scripting
Solução:
// faz escaping de caracteres perigosos (<, >, ", etc.)
import org.apache.commons.text.StringEscapeUtils;
String safeQ = StringEscapeUtils.escapeHtml4(q);
OU document.getElementById("out").textContent = userInput; // trata como texto
CSRF - Cross Site Request Forgery
Problema: O navegador da vítima enviar uma requisição válida (com cookies/sessão ativos) para outro sistema em que ela já está autenticada.
Exemplo: Você está logado no seu internet banking, visita uma página maliciosa, ela dispara um POST /transferir em segundo plano e o servidor recebe como se fosse você.
CSRF - Cross Site Request Forgery
CSRF - Cross Site Request Forgery
Solução:
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().and() // habilita proteção
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
return http.build();
}
}
CSRF - Cross Site Request Forgery
Solução:
<input type="hidden" name="_csrf" value="abc123">
CSRF - Cross Site Request Forgery
Exposição de PII (Personal Identification Information)
Problema: Dados como CPF sendo expostos em logs, métricas, etc (Pode gerar problemas com LGPD)
Solução: Mascarar dados sensíveis.
Actuator expondo dados sensíveis via heap dump
Problema: /actuator/heapdump permite o download da heap.
Solução:
management.endpoint.heapdump.enabled=false
Segredos em código/properties
Problema: senha do DB ou token de API no application.properties
(db.password=123456)
Solução: Usar o Azure Keyvault
Usando Azure Key Vault
# Endereço do seu Key Vault
spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=https://meu-vault.vault.azure.net/
spring.cloud.azure.keyvault.secret.property-source-enabled=true
# Credenciais de autenticação (App Registration no Azure AD)
spring.cloud.azure.keyvault.secret.property-sources[0].credential.client-id=11111111-2222-3333-4444-555555555555
spring.cloud.azure.keyvault.secret.property-sources[0].credential.client-secret=SEU_CLIENT_SECRET
spring.cloud.azure.keyvault.secret.property-sources[0].profile.tenant-id=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
# ===============================
# Exemplo de uso dos segredos
# (esses nomes vêm dos segredos no Key Vault)
# ===============================
spring.datasource.url=${secretDbUrl}
spring.datasource.username=${secretDbUser}
spring.datasource.password=${secretDbPassword}
Agora, só problemas de autenticação
ou de autorização
Problemas de Autenticação e Autorização
Problema 1: Senha armazenada em texto puro
Solução:
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12); // custo ajustável
String hash = encoder.encode(password);
userRepository.save(new User(email, hash));
Problemas de Autenticação e Autorização
Problema 2: Brute force attack
Solução:
1 - Usar captchas
2 - Bloquear o usuário após X tentativas
Problemas de Autenticação e Autorização
Problema 3: Manter a mesma session id antes/após login. - Atacante pode usar o id de uma sessão conhecida.
Problemas de Autenticação e Autorização
Problema 3: ��Fornecendo uma
sessão compro-
metida
Problemas de Autenticação e Autorização
Solução:
No Spring Security: habilitar sessionFixation().migrateSession()
Problemas de Autenticação e Autorização
Problema 4: Guardar JWT em localStorage -> acessível por XSS.
Solução: Armazenar access token em cookie HttpOnly + Secure + SameSite, usar refresh token rotativo.
ResponseCookie cookie = ResponseCookie.from("access_token", token)
.httpOnly(true).secure(true).path("/").sameSite("Strict")
.maxAge(Duration.ofMinutes(15)).build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
Problemas de Autenticação e Autorização
Problema 5: IDOR - Id of Object Reference
https://site.com/minha-conta/fatura?id=123
(Qualquer um pode acessar a fatura 123)
Solução:
Problemas de Autenticação e Autorização
Problema 6: Validação só no Frontend
frontend esconde botão “apagar”,
backend permite DELETE /users/{id} sem checagem.
Solução:
Usar Spring Security method-level checks:
@PreAuthorize("#id == principal.id or hasRole('ADMIN')")
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable Long id) { ... }
Problemas de Autenticação e Autorização
Problema 7: Aceitar role JWT vindo do cliente sem validar assinatura.
Solução: Assinar tokens (JWT) com chave forte e validar token no servidor
@PreAuthorize("hasAuthority('SCOPE_admin')")
Problemas de Autenticação e Autorização
Problema 8: Apenas apagar cookie no cliente sem invalidar token server-side (refresh tokens continuam válidos).
Solução: Manter lista de refresh tokens server-side
public void logout(String refreshToken) { . . .
refreshTokenRepository.revoke(refreshTokenId);
// limpar cookie do cliente
}
3 - “Zero Trust: nunca confie, sempre valide”
3.1 - Zero Trust no Filesystem
Zero Trust no Filesystem
Tratar todo o FS como não confiável por padrão, liberando só o mínimo necessário e validando tudo.�
Zero Trust no Filesystem
Sugestão para isto: Usar o Red Hat UBI (Universal Base Image)
Zero Trust no Filesystem
FROM registry.access.redhat.com/ubi9/openjdk-21:1.20
# copia o jar ou fat jar
COPY target/myapp-1.0-runner.jar /deployments/app.jar
# apenas defina a execução
CMD ["java", "-jar", "/deployments/app.jar"]
3.2 - Zero Trust na Rede
Zero Trust a nível de rede - 1
Problema:
Zero Trust a nível de rede - 1
Solução: Definir NetworkPolicies para limitar comunicação
Exemplo: só permitir que api acesse db na porta 5432
kind: NetworkPolicy
spec:
podSelector: {}
ingress: [] # bloqueia tudo por padrão
kind: NetworkPolicy
spec:
podSelector:
matchLabels: { app: db }
ingress:
- from:
- podSelector: { app: api }
ports:
- protocol: TCP
port: 5432
Zero Trust a nível de rede - 2
Problema:
Zero Trust a nível de rede - 2
Solução: Usar Service Mesh (Istio, OpenShift Service Mesh) e ativar mTLS: criptografia e autenticação mútua automática
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
spec:
mtls:
mode: STRICT
Zero Trust a nível de rede - 3
Problema:
A maioria das comunicações são internas ou de entrada
Mas a saída DEVE ser bloqueada
✓
Zero Trust a nível de rede - 3
Solução: Definir EgressRules em Service Mesh ou políticas de rede
Exemplo: permitir saída apenas para APIs confiáveis (ex.: pagamentos)
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
spec:
hosts: ["api.pagamentos.com"]
ports:
- number: 443
name: https
protocol: TLS
3.3 - Zero Trust no Banco de Dados
Zero Trust a nível de banco de dados -1
Problema:
Solução:
Zero Trust a nível de banco de dados -2
Problema:
Solução:
Zero Trust a nível de banco de dados -3
Problema:
Solução:
Zero Trust a nível de banco de dados - 4
Problema:
Solução:
Zero Trust a nível de banco de dados - 4
Problema:
Solução:
5 - Segurança reforçada com ARO
“O código já é seguro. Agora precisamos garantir que ele rode em uma plataforma igualmente segura.”
Responsabilidade compartilhada reforçada
Datacenters certificados (ISO 27001, SOC 2, GDPR, etc.)
Patching contínuo, atualização automática de CVEs, hardening validado
Controle granular com RBAC, NetworkPolicy e SCC
Cluster com hardening corporativo Red Hat
O ARO utiliza imagens Red Hat Enterprise Linux CoreOS (RHCOS), com:
Isso entrega uma base zero trust já embutida na camada do host e do sistema operacional.
Isolamento de rede e compliance com Azure Security Center
Isso atende normas como LGPD, PCI-DSS e ISO 27001 sem precisar configurar tudo manualmente.
Gestão de identidade e acesso integrada
Com isso, você aplica o Princípio do Menor Privilégio de ponta a ponta — desde o login até o pod.
Supply Chain e imagens seguras
ARO permite:
Isso reduz o risco de supply chain attacks — uma das maiores preocupações atuais (vide SolarWinds, Log4Shell, etc).
Observabilidade e auditoria nativas
Com isso, o cliente tem rastreabilidade e capacidade de resposta rápida a incidentes.
6 - Demonstração usando uma aplicação Spring Boot
7 - Encerramento
“Segurança não é projeto, é prática diária.”
Como aplicar Shift Left no dia a dia
Como aplicar Zero Trust no dia a dia
Como aplicar Supply Chain no dia a dia
Por fim…
"Em um mundo que não para de se mover, estar seguro em Java significa estar pronto para o futuro.”
Dúvidas? Ideias?
Vamos conversar!