As vulnerabilidades de segurança são mais fáceis de prevenir do que de corrigir. Uma falha de injeção de SQL detectada em uma revisão de código leva minutos para ser corrigida. A mesma falha, descoberta após uma violação de segurança, custa semanas de resposta a incidentes, investigação regulatória e remediação, além de quaisquer dados que tenham sido exfiltrados nesse período. A análise estática de código é a disciplina que consiste em encontrar esses problemas antes da execução do código, examinando a estrutura do código-fonte, o fluxo de dados e os padrões em comparação com assinaturas de vulnerabilidades conhecidas. Aplicada sistematicamente, ela transforma a segurança de uma prática reativa em uma propriedade intrínseca do processo de desenvolvimento.
O OWASP Top 10 é o catálogo definitivo dos riscos de segurança mais críticos para aplicações web, atualizado pelo Open Web Application Security Project com base em dados reais de vulnerabilidades em milhares de aplicações. Cada item da lista é detectável, em diferentes graus, por ferramentas de análise estática. Este guia mapeia cada categoria do OWASP para o que a análise estática pode encontrar, mostra o padrão de código vulnerável e seu equivalente seguro, e explica quais ferramentas aplicam cada técnica.
Descubra a injeção antes que os atacantes o façam.
SMART TS XL Rastreia vulnerabilidades desde APIs JavaScript, passando por serviços Java, até back-ends COBOL.
Mais informaçõesO que é o Teste Estático de Segurança de Aplicações (SAST)?
O Teste Estático de Segurança de Aplicações (SAST, na sigla em inglês) analisa o código-fonte, bytecode ou binário sem executar o programa. A análise examina como os dados fluem pela aplicação, quais operações sensíveis à segurança esses dados alcançam e se algum caminho a partir de uma entrada externa (entrada do usuário, parâmetros HTTP, conteúdo de arquivos, variáveis de ambiente) leva a uma operação perigosa (consulta a banco de dados, comando do sistema, saída HTML, função criptográfica) sem a devida validação ou sanitização.
SAST é uma camada em um programa completo de segurança de aplicações. Para entender onde ela se encaixa, é preciso compará-la com as alternativas:
| Abordagem | Quando funciona | O que encontra | O que falta |
|---|---|---|---|
| SAST (Estático) | Antes da execução, no código-fonte | Vulnerabilidades no código, padrões de injeção, uso indevido de criptografia, segredos embutidos no código. | Vulnerabilidades exclusivas de tempo de execução, problemas de configuração na implantação. |
| DAST (Dinâmico) | Contra um aplicativo em execução | Comportamento em tempo de execução, falhas de autenticação, problemas de configuração do servidor | Padrões de nível de código não acionados durante os testes |
| SCA (Análise de Composição de Software) | Sobre as manifestações de dependência | Vulnerabilidades críticas conhecidas (CVEs) em bibliotecas de terceiros | Vulnerabilidades de código personalizado |
| IAST (Interativo) | Durante a execução de testes com instrumentação | Fluxos de dados em tempo de execução com alta precisão | Requer aplicativo em execução, feedback mais lento |
O SAST fornece o feedback mais precoce, pois é executado em código que ainda não foi implantado, no pipeline de CI/CD ou mesmo no IDE, antes que a vulnerabilidade chegue a um ambiente de teste. Essa precocidade é seu principal valor em termos de segurança.
Que tipos de ameaças a análise estática de código pode mitigar?
Essa é uma das perguntas mais pesquisadas sobre SAST. A resposta direta é:
A análise estática de código pode mitigar ameaças que se manifestam em padrões de código-fonte : vulnerabilidades de injeção (SQL, comandos, XSS), uso indevido de criptografia, credenciais embutidas no código, implementações de autenticação inseguras, falhas no controle de acesso na lógica do código e falhas de integridade de dados. Ela não pode mitigar ameaças que surgem da configuração em tempo de execução, topologia de rede ou configuração de infraestrutura; essas exigem DAST (Análise de Segurança de Dados e Testes de Ativação), testes de penetração ou varredura de segurança de infraestrutura.
Análise Estática vs. Análise Dinâmica para Cobertura OWASP
A análise dinâmica (DAST) e a análise estática (SAST) encontram subconjuntos diferentes de vulnerabilidades da OWASP. Nenhuma delas abrange tudo. O Guia de Testes de Segurança Web da OWASP (WSTG) é a estrutura metodológica para testes dinâmicos; ferramentas SAST como CodeQL, Semgrep e SonarQube atuam na camada de código-fonte.
| Categoria OWASP Top 10 | Cobertura SAST | Cobertura DAST |
|---|---|---|
| Controle de acesso quebrado | Parcial, lacunas na lógica do código | Bom teste de comportamento em tempo de execução |
| Falhas Criptográficas | Detecção forte por algoritmo | Fraco, difícil de observar de fora. |
| Injeção | Análise de contaminação forte | Testes de carga útil robustos e ativos |
| Design inseguro | Detecção parcial de padrões | Fraco, requer conhecimento de design. |
| Configuração incorreta de segurança | Parcial, configuração no código | Testes robustos em ambiente real |
| Componentes Vulneráveis | Fraco, SCA é melhor | Fraco, SCA é melhor |
| Falhas de autenticação | Credenciais parciais e codificadas, padrões fracos | Testes robustos de sessão e autenticação |
| Falhas de integridade de dados | Padrões de desserialização parciais | Fraco, difícil de detectar externamente |
| Falhas de registro | Declarações de log parciais ou ausentes | Ausência fraca e difícil de observar |
| SSRF | Forte, contaminar a chamada HTTP | Testes de solicitação fortes e ativos |
Conclusão: SAST e DAST são complementares. Para obter a máxima cobertura da OWASP, execute ambos. Para equipes com orçamento limitado que estão começando do zero, priorize o SAST, pois ele fornece o feedback mais rápido dos desenvolvedores e a cobertura de injeção mais abrangente.
OWASP Top 10: O que a análise estática descobre e como.
A01, Controle de Acesso Quebrado
O controle de acesso falho é o principal risco da OWASP. A análise estática aborda as manifestações no nível do código: ausência de verificações de autorização em funções e endpoints, referências a objetos que expõem IDs internos sem validação e atribuições de funções codificadas que ignoram as estruturas de permissão pretendidas.
O que a análise estática detecta: Métodos que lidam com operações sensíveis sem uma verificação de autorização correspondente; referências diretas a objetos onde o ID do objeto vem da entrada do usuário sem validação de acesso; padrões de navegação forçada onde o estado autenticado é verificado, mas a propriedade do objeto não.
Java
// Vulnerable: no ownership check -- any authenticated user can access any order
@GetMapping("/orders/{orderId}")
public Order getOrder(@PathVariable Long orderId) {
return orderRepository.findById(orderId).orElseThrow();
}
// Secure: verify the order belongs to the requesting user
@GetMapping("/orders/{orderId}")
public Order getOrder(@PathVariable Long orderId,
@AuthenticationPrincipal UserDetails user) {
Order order = orderRepository.findById(orderId).orElseThrow();
if (!order.getOwnerId().equals(user.getUserId())) {
throw new AccessDeniedException("Order does not belong to requesting user");
}
return order;
}
O que a análise estática não consegue detectar: falhas de controle de acesso em tempo de execução, onde a lógica está correta, mas os dados usados para tomar a decisão estão comprometidos. Nesses casos, são necessários testes DAST e de penetração.
A02, Falhas Criptográficas
A criptografia fraca é detectável de forma confiável por meio de análise estática, pois os padrões vulneráveis, como MD5, SHA-1, DES, modo ECB e chaves codificadas, são identificáveis lexicalmente no código-fonte.
python
# Vulnerable: MD5 for password hashing (broken algorithm)
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()
# Vulnerable: hardcoded encryption key
KEY = b"mysecretkey12345"
cipher = AES.new(KEY, AES.MODE_ECB) # ECB mode also vulnerable
# Secure: bcrypt for passwords, environment-sourced keys
import bcrypt, os
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# Secure: AES-GCM with environment-sourced key
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
key = os.environ["ENCRYPTION_KEY"].encode()
aesgcm = AESGCM(key)
Sinalizador de regras de análise estática: MD5/SHA-1 para fins de segurança, modo DES/3DES/RC4/ECB, chaves e segredos criptográficos embutidos, HTTP em vez de HTTPS para transmissão de dados sensíveis e verificação de certificado desativada (verify=False em solicitações Python, setHostnameVerifier(ALLOW_ALL_HOSTNAME_VERIFIER) em Java).
A03, Injeção
Injeção, SQL, comandos do sistema operacional, LDAP, XSS e injeção de modelos são as categorias em que a análise de contaminação interprocedural oferece seu valor mais direto. A vulnerabilidade exige o rastreamento de entradas não confiáveis desde sua origem, passando por chamadas de função, até um destino perigoso.
javascript
// Vulnerable: direct string interpolation in SQL (SQL injection)
app.get('/users', async (req, res) => {
const name = req.query.name;
const result = await db.query(`SELECT * FROM users WHERE name = '${name}'`);
res.json(result.rows);
});
// Secure: parameterized query
app.get('/users', async (req, res) => {
const name = req.query.name;
const result = await db.query('SELECT * FROM users WHERE name = $1', [name]);
res.json(result.rows);
});
php
// Vulnerable: unescaped output (XSS)
echo "Welcome, " . $_GET['username'];
// Secure: context-appropriate escaping
echo "Welcome, " . htmlspecialchars($_GET['username'], ENT_QUOTES, 'UTF-8');
csharp
// Vulnerable: command injection in C#
var process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c " + userInput;
process.Start();
// Secure: avoid shell interpretation, validate and whitelist inputs
var allowedCommands = new HashSet<string> { "report", "export" };
if (!allowedCommands.Contains(userInput))
throw new ArgumentException("Invalid command");
Ferramentas que realizam análise de contaminação interprocedural para injeção: CodeQL (mais preciso), Semgrep com modo de contaminação, Snyk Code, SonarQube com regras de segurança.
A04, Design Inseguro
O design inseguro é a categoria mais difícil da OWASP para análise estática, pois diz respeito a decisões arquiteturais em vez de padrões de código. A análise estática pode sinalizar os seguintes sintomas:
Ausência de lógica de limitação de taxa nos endpoints de autenticação, falta de bloqueio de conta após tentativas falhas, lógica de negócios que ignora etapas de validação e funções que executam operações privilegiadas sem registro de auditoria. Esses problemas são detectáveis como padrões ausentes, uma análise estática que relata o que está ausente em vez do que está presente.
Algumas ferramentas SAST suportam regras personalizadas que podem codificar requisitos de segurança organizacional: cada método de controlador deve chamar uma função de autorização, cada gravação no banco de dados deve ser precedida por validação de entrada, cada chamada de API externa deve usar um tempo limite. Essas regras personalizadas convertem requisitos de design em restrições de código aplicáveis.
A05, Configuração de segurança incorreta
Configurações de segurança incorretas no código incluem: recursos de segurança desativados, cabeçalhos CORS permissivos, cabeçalhos de resposta de segurança ausentes, modo de depuração ativado em produção e mensagens de erro detalhadas que expõem rastreamentos de pilha.
python
# Vulnerable: Flask debug mode enables interactive debugger in production
app = Flask(__name__)
app.run(debug=True) # exposes console access if error occurs
# Vulnerable: overly permissive CORS
from flask_cors import CORS
CORS(app, origins="*") # allows any origin
# Secure: environment-controlled debug, restricted CORS
import os
debug_mode = os.environ.get("FLASK_DEBUG", "false").lower() == "true"
CORS(app, origins=os.environ.get("ALLOWED_ORIGINS", "").split(","))
app.run(debug=debug_mode)
Sinalizador de regras de análise estática: modo de depuração definido como True Na origem, existem CORS com curinga, cabeçalhos de segurança ausentes nas configurações de resposta HTTP, verificação de certificado SSL desativada e credenciais padrão nos arquivos de configuração.
A06, Componentes Vulneráveis e Desatualizados
Esta categoria é abordada principalmente pela Análise de Composição de Software (SCA) em vez da Análise de Sistemas de Teste de Software (SAST) tradicional. A SCA realiza varreduras. package.json, pom.xml, requirements.txte manifestos semelhantes em relação a bancos de dados de vulnerabilidades (National Vulnerability Database, GitHub Advisory Database).
O SAST contribui identificando o uso de APIs obsoletas, chamadas a funções de biblioteca que foram substituídas devido a falhas de segurança ou o uso direto de padrões vulneráveis que até mesmo bibliotecas atualizadas não recomendam mais.
Ferramentas específicas para A06: npm audit, pip-audit, snyk test, OWASP Dependency-Check, GitHub Dependabot e Mend (anteriormente WhiteSource).
A07, Falhas de Identificação e Autenticação
A análise estática identifica os seguintes antipadrões de autenticação em nível de código: senhas embutidas no código, validação de senha fraca, tokens de sessão gerados com aleatoriedade não criptográfica, ausência de invalidação de sessão ao sair e implementações de JWT que aceitam o none algoritmo.
javascript
// Vulnerable: JWT accepting 'none' algorithm -- allows signature bypass
const decoded = jwt.verify(token, secret, { algorithms: ['HS256', 'none'] });
// Vulnerable: hardcoded admin credentials
if (username === 'admin' && password === 'admin123') {
grantAccess();
}
// Secure: algorithm whitelist, no hardcoded credentials
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
algorithms: ['HS256'] // explicit allowlist only
});
csharp
// Vulnerable: weak random for session token generation in C#
var sessionToken = new Random().Next().ToString();
// Secure: cryptographically secure random
using var rng = RandomNumberGenerator.Create();
var bytes = new byte[32];
rng.GetBytes(bytes);
var sessionToken = Convert.ToBase64String(bytes);
A08, Falhas de Integridade de Software e Dados
Esta categoria abrange desserialização insegura e atualizações de software não verificadas. A análise estática detecta: Java ObjectInputStream Desserializando dados de fontes não confiáveis, Python pickle.loads() em dados externos, PHP unserialize() com entrada controlada pelo usuário e analisadores YAML que utilizam carregadores inseguros.
python
# Vulnerable: pickle deserialization of untrusted data
import pickle
data = pickle.loads(request.data) # arbitrary code execution risk
# Vulnerable: unsafe YAML loader
import yaml
config = yaml.load(user_input) # yaml.load without Loader is unsafe
# Secure: safe alternatives
import json
data = json.loads(request.data) # JSON cannot execute code
import yaml
config = yaml.safe_load(user_input) # safe_load disables arbitrary object creation
A09, Falhas no registro e monitoramento de segurança
Falhas no registro de logs podem ser detectadas por análise estática como padrões ausentes: operações sensíveis, eventos de autenticação, decisões de controle de acesso, modificações de dados, que ocorrem sem as respectivas instruções de log. As regras de análise estática podem exigir que certas chamadas de função sempre ocorram em conjunto com chamadas de log de auditoria.
O que a análise estática identifica: registro de senhas ou tokens (o registro de dados sensíveis também é uma vulnerabilidade), manipuladores de exceção que ignoram erros silenciosamente sem registrá-los e blocos catch que registram a mensagem de exceção bruta (que pode conter dados sensíveis).
Java
// Vulnerable: swallowed exception, no logging
try {
authenticateUser(username, password);
} catch (Exception e) {
// silent failure -- no log, no audit trail
}
// Vulnerable: logging sensitive data
log.info("User logged in with password: " + password);
// Secure: log the event, not the credential
try {
authenticateUser(username, password);
auditLog.info("Authentication success for user: {}", username);
} catch (AuthenticationException e) {
auditLog.warn("Authentication failure for user: {}", username);
throw e; // do not swallow
}
A10, Falsificação de Requisição do Lado do Servidor (SSRF)
SSRF é um caso típico para análise de contaminação interprocedural. A vulnerabilidade exige o rastreamento da entrada controlada pelo usuário até uma requisição HTTP, frequentemente por meio de múltiplas chamadas de função. Uma ferramenta que analisa apenas funções individuais não consegue detectar SSRF quando a construção da URL e a chamada HTTP ocorrem em funções diferentes.
python
# Vulnerable: user-controlled URL in HTTP request (SSRF)
import requests
def fetch_resource(url):
return requests.get(url).content # no validation
def api_endpoint(request):
target = request.json().get("url") # attacker controls this
return fetch_resource(target) # SSRF across function boundary
# Secure: allowlist validation before making the request
from urllib.parse import urlparse
ALLOWED_HOSTS = {"api.internal.example.com", "cdn.example.com"}
def fetch_resource(url: str) -> bytes:
parsed = urlparse(url)
if parsed.hostname not in ALLOWED_HOSTS:
raise ValueError(f"URL host not allowed: {parsed.hostname}")
return requests.get(url, timeout=5).content
Ferramentas de análise estática de código para segurança OWASP
A tabela abaixo relaciona as principais ferramentas SAST às categorias OWASP que elas abordam com maior eficácia:
| ferramenta | Idiomas primários | Pontos fortes da OWASP | Abordagem |
|---|---|---|---|
| Código QL | Java, JS/TS, Python, C/C++, Go, Ruby | Injeção A03, SSRF A10 (contaminação profunda) | Análise semântica interprocedimental |
| Semgrep | Mais de 30 idiomas | A03, A02, A07 (modo baseado em padrão + modo de contaminação) | Correspondência de padrões + períneo superficial |
| Código Snyk | Java, JS/TS, Python, C# | A03, A07, A08 | Análise de contaminação baseada em aprendizado de máquina |
| SonarQubeGenericName | Mais de 30 idiomas | A02, A03, A05, A07, A09 | Baseado em regras + fluxo de dados |
| check-marx | Mais de 30 idiomas | Cobertura completa da OWASP | Contaminação interprocedimental |
| veracode | Java, .NET, JS, PHP | Cobertura completa da OWASP | Análise de bytecode e contaminação |
| ZAP OWASP | Independente de idioma | A01, A05, A07 (tempo de execução) | DAST, testes dinâmicos |
| SMART TS XL | COBOL, JCL, Java, Python, RPG, SQL | Contaminação entre idiomas, risco de dependência | Estrutura interlinguística + contaminação |
Como SMART TS XL Aborda a segurança em bases de código corporativas
Os programas de segurança corporativa enfrentam um desafio que as ferramentas SAST de linguagem única não conseguem resolver: a superfície de ataque abrange várias linguagens. Um aplicativo web pode aceitar entrada do usuário em JavaScript, processá-la em Java, passá-la por uma fila de mensagens para um programa COBOL que executa SQL em um banco de dados DB2. A vulnerabilidade de injeção existe em quatro linguagens diferentes. Nenhum scanner de linguagem individual consegue enxergar todo o caminho de contaminação.
SMART TS XL'S análise de código estático Abrange todas as linguagens nessa cadeia simultaneamente. Quando uma entrada não confiável flui de um manipulador de API JavaScript por meio de um serviço Java para um programa COBOL que constrói uma consulta SQL dinâmica, SMART TS XL traça esse caminho em todo o grafo de chamadas entre linguagens, o mesmo rastreamento de contaminação interprocedural que o CodeQL aplica em Java, aplicado em Java, COBOL e SQL simultaneamente.
A capacidade de mapeamento de dependências de aplicativos fornece a visão relevante para a segurança de quais componentes do sistema interagem com entradas externas, quais alcançam operações privilegiadas e qual é a superfície de ataque completa do sistema. Essa visão arquitetural de segurança é a base para a modelagem de ameaças; não é possível modelar ameaças contra um sistema cuja estrutura você não compreende.
A funcionalidade de análise de impacto serve aos programas de remediação de segurança: quando uma vulnerabilidade é encontrada em um componente, a análise de impacto identifica todos os outros componentes que dependem do componente vulnerável, dimensionando com precisão o esforço de remediação antes que qualquer alteração no código seja feita. Para grandes bases de código legadas, onde um programa COBOL com uma falha de segurança é incluído por centenas de outros programas, conhecer o escopo completo da remediação antes de começar é a diferença entre uma correção gerenciada e um incidente em cascata.
Para organizações que gerenciam modernização legada Em programas, a análise de segurança do código legado é um pré-requisito, não uma reflexão tardia. Migrar programas COBOL vulneráveis para Java resulta em programas Java vulneráveis. SMART TS XLA análise de segurança da [nome da empresa] garante que as vulnerabilidades sejam identificadas e corrigidas como parte do processo de modernização, e não descobertas no sistema migrado.
Integrando SAST ao ciclo de vida do desenvolvimento
A análise estática de segurança oferece seu valor máximo quando executada no momento da tomada de decisão, durante a escrita e revisão do código, e não após sua implantação.
Na IDE: SonarLint, extensões da Snyk para IDEs e a extensão do CodeQL para VS Code exibem as vulnerabilidades diretamente no código enquanto os desenvolvedores escrevem. Um alerta de injeção de SQL que aparece no momento em que um desenvolvedor digita o padrão vulnerável leva segundos para ser corrigido.
Em pull requests: o SAST integrado ao GitHub Actions, GitLab CI ou Jenkins é executado em cada pull request e publica as descobertas como comentários de revisão de código embutidos. O desenvolvedor vê a descoberta em contexto, junto com o código que a causou.
Como um mecanismo de controle de qualidade: o modelo de controle de qualidade do SonarQube bloqueia fusões quando novos pontos críticos de segurança são introduzidos. Isso faz com que a segurança não seja uma etapa de revisão opcional, mas um requisito estrutural do processo de fusão.
De forma programada: Análise interprocedural profunda, CodeQL, Checkmarx, conjuntos completos de regras Semgrep, geralmente muito lenta para execução por commit, mas executada diariamente ou semanalmente na branch principal, encontrando vulnerabilidades que exigem análise completa do grafo de chamadas para serem detectadas.
A abordagem em camadas, com regras rápidas baseadas em padrões no IDE e nos commits, além de uma análise profunda de contaminação em pull requests e nas versões noturnas, oferece tanto a agilidade que os desenvolvedores precisam quanto a abrangência exigida pelos programas de segurança.