pular para o conteúdo
voltar ao mapa
técnica de teste
etapa: build / PR
3 min de leitura

SAST

Raio-x do código sem executar nada: acha padrões vulneráveis antes do primeiro deploy.

SemgrepCodeQLSonarQubeCheckmarx

O que é

(Static Application Security Testing) analisa o código-fonte, bytecode ou binário sem executar o programa. O scanner procura construções perigosas — concatenação de SQL, , criptografia fraca, — e aponta arquivo e linha, no formato que o desenvolvedor já consome.

A sigla esconde três técnicas bem diferentes: pattern matching (regras textuais), análise de fluxo de dados (o famoso ) e análise semântica. Sem entender as três, o output do scanner parece mágica — e os falsos positivos parecem bug.

Do texto ao AST

Antes de qualquer análise, o código passa por um parser e vira uma AST (): cada construção da linguagem vira um nó tipado, e o scanner navega nessa árvore em vez de ler texto solto. É isso que permite perguntar coisas como 'existe um nó de concatenação dentro de uma chamada de query?'.

Uma linha inocente de JavaScript vira uma árvore assim:

sql.js → ASTtext
const sql = "SELECT * FROM users WHERE id = " + req.query.id

VariableDeclaration
  id:   Identifier "sql"
  init: BinaryExpression "+"
          left:  StringLiteral "SELECT * FROM users WHERE id = "
          right: MemberExpression
                   req.query.id

Source → sink: o coração da análise

A AST sozinha diz que existe uma concatenação — não diz se ela é perigosa. A pergunta de segurança é outra: esse dado tem origem confiável? Onde ele termina?

Taint analysis (análise de contaminação) responde seguindo o dado: fontes não confiáveis — input do usuário, headers, query strings — são marcadas como 'tainted'. O engine propaga essa marca por atribuições, concatenações e chamadas de função, e dispara o alerta quando a marca chega a um sink: um ponto onde o dado vira comando, query, HTML ou caminho de arquivo.

No exemplo abaixo, o fluxo é completo: nasce em req.query.id (source), atravessa uma concatenação (propagação) e termina dentro de db.query (sink):

server.js — vulneráveljavascript
app.get("/users", (req, res) => {
  const id = req.query.id;                                // SOURCE
  const sql = "SELECT * FROM users WHERE id = " + id;     // propagação
  db.query(sql, (err, rows) => res.json(rows));           // SINK
});

O que o scanner reporta

O resultado não é 'existe concatenação' — é o caminho inteiro, com e correção sugerida. Algo como:

saída do scannertext
server.js:3
  SQL Injection (CWE-89) · alta
  taint:  req.query.id -> id -> sql -> db.query()
  fix:    use query parametrizada (placeholder $1)

A correção que o engine aceita

Parametrizar a query interrompe a taint: o valor do usuário deixa de ser código e vira dado. Na linguagem do taint analysis, o é um sanitizador (ou barrier) — o engine sabe que aquele caminho específico está limpo e para de alertar nele.

server.js — corrigidojavascript
app.get("/users", (req, res) => {
  const sql = "SELECT * FROM users WHERE id = $1";        // query fixa
  db.query(sql, [req.query.id], (err, rows) => res.json(rows));
});

Onde entra na pipeline

O mais cedo possível: plugin de IDE e pre-commit dão feedback em segundos, a análise completa roda no PR e no stage de build. Regras críticas quebradas falham o build () e bloqueiam o merge.

Pontos fortes

  • cobertura de 100% do código, inclusive caminhos raramente executados
  • acha a vulnerabilidade cedo, quando corrigir custa pouco
  • não precisa de ambiente rodando nem de credenciais

Limitações

  • falsos positivos: quando o engine não consegue provar que o caminho é seguro (um sanitizador customizado, por exemplo), ele alerta por precaução — e a triagem é trabalho humano
  • explosão de caminhos: analisar todas as combinações de execução é caro; os engines usam heurísticas e podem perder fluxos raros
  • é cego para configuração de runtime, infraestrutura e comportamento real — território do DAST
SASTAnálise estática: examina o código sem executar. Acha por análise de fluxo, não por adivinhação.ver no glossário →Desserialização inseguraReconstruir objetos a partir de bytes não confiáveis usando um formato que pode instanciar tipos arbitrários (serialização Java, pickle). Os bytes podem provocar execução de código.ver no glossário →XSScross-site scriptingInjeção em uma página web: entrada não confiável é renderizada como HTML ou script no navegador de outro usuário. Faça escape na saída conforme o contexto e adicione uma Content-Security-Policy.ver no glossário →Taint trackinganálise de contaminaçãoSeguir a marca de 'dado sujo' do source até o sink, propagando por atribuições e chamadas. É o coração do SAST moderno.ver no glossário →ASTabstract syntax treeA árvore de sintaxe que o parser produz: cada construção do código vira um nó tipado, e as ferramentas analisam a árvore em vez de texto solto.ver no glossário →CWEcommon weakness enumerationO identificador do TIPO de fraqueza, a classe do erro no código. CWE-89 é SQL injection, CWE-79 é XSS. A distinção que confunde todo mundo: CWE é a categoria, CVE é uma ocorrência concreta dela — uma CVE de SQL injection no seu framework vai referenciar o CWE-89.ver no glossário →Prepared statementconsulta parametrizadaUma consulta cuja estrutura é fixada antes de qualquer valor ser fornecido, de modo que o banco de dados não confunde dados com instruções.ver no glossário →Quality gateO portão explícito de um stage: 'falha o build se houver achado crítico novo'. Sem critério claro, gate vira sugestão.ver no glossário →

conexões no mapa

atualizado em 14/10/2026 · fontes para aprofundar · reportar erro

em outros domínios

Estude antes

Desbloqueia

teste o que entendeu

Carregando perguntas…