In this article
Primeiros passos com análise estática de JavaScript
Ao escrever código JavaScript, a análise estática é fundamental para manter a qualidade e a legibilidade do código e garantir sua segurança. Esse processo automatizado verifica o código-fonte antes da execução para identificar padrões problemáticos, bugs, vulnerabilidades e erros que podem levar a sérios problemas de segurança ou falhas na aplicação.
JavaScript é uma linguagem conhecida por seu dinamismo e flexibilidade, por isso a análise estática pode ser especialmente valiosa. Ela pode compensar a ausência de um compilador tradicional, oferecendo aos desenvolvedores uma forma de detectar possíveis problemas no início do ciclo de desenvolvimento. Esse provavelmente é um dos motivos pelos quais você já considerou adotar TypeScript, certo?
Entenda a análise estática
A análise estática, também conhecida como análise estática de código, é um método de depuração que examina o código-fonte automaticamente antes da execução de um programa. Ela analisa um conjunto de código com base em um ou mais conjuntos de regras de programação.
A análise estática consiste em inspecionar o código-fonte de uma aplicação de software sem executá-la. Diferentemente da análise dinâmica, que avalia o código durante a execução, a análise estática é realizada fora do ambiente de execução. Esse método é essencial para encontrar erros, bugs e outros problemas que podem prejudicar a aplicação ou suas funcionalidades. Também ajuda os desenvolvedores a entender a base de código, garantir sua qualidade e manter os padrões de programação em todo o projeto.
Em JavaScript, a análise estática pode ser feita com ferramentas como ESLint, JSHint e TSLint. Veja um exemplo simples de como o ESLint funciona:
var user = {};
console.log(user.name);Ao executar o ESLint nesse código, você receberá um aviso: Unexpected console statement no-console
Esse aviso ajuda os desenvolvedores a evitar o uso de instruções console.log no código de produção, prática considerada inadequada.
Análise estática vs. dinâmica
Vamos analisar a fundo a análise estática e a dinâmica e entender as vantagens da análise estática em determinadas situações.
Veja um exemplo de análise estática com o ESLint:
const ESLint = require('eslint');
const eslint = new ESLint({ fix: true });
async function lintCode() {
const results = await eslint.lintFiles(["./**/*.js"]);
await ESLint.outputFixes(results);
}
lintCode().catch((error) => {
process.exitCode = 1;
console.error(error);
});
Este script usa a API programática do ESLint para fazer análise estática em todos os arquivos JavaScript do seu projeto, corrigindo os problemas que puder ao longo do processo.
O que é análise dinâmica?
Já a análise dinâmica examina uma aplicação durante sua execução. Ela oferece uma visão em tempo real do desempenho, do comportamento e dos resultados do sistema. Ao contrário da análise estática, a análise dinâmica exige que o programa esteja em execução. Ela costuma ser usada na depuração para encontrar problemas de execução que a análise estática pode não detectar.
Por exemplo, ao usar JavaScript no navegador ou em um ambiente de execução Node.js, você pode usar console.time() e console.timeEnd() para fazer uma análise dinâmica:
function someFunction() {
// Some code here...
}
console.time('someFunction');
someFunction();
console.timeEnd('someFunction');Este script exibirá o tempo que someFunction () leva para ser executada, oferecendo uma forma simples de análise dinâmica.
Em aplicações Node.js nativas, você pode usar o módulo integrado node:perf_hooks para medir o tempo de execução de uma função:
const { performance } = require('perf_hooks');
function someFunction() {
// Some code here...
}
const start = performance.now();
someFunction();
const end = performance.now();
console.log(`Time taken: ${end - start}ms`);Em segurança de aplicações, as ferramentas de teste dinâmico de segurança de aplicações (DAST) são usadas para analisar aplicações web em execução. Elas podem ajudar a identificar vulnerabilidades de segurança, como ataques de injeção, cross-site scripting (XSS) e outras. Saiba mais sobre SAST vs. DAST e como combinar os dois.
As vantagens da análise estática sobre a dinâmica em determinadas situações
A análise estática e a dinâmica têm vantagens próprias e costumam ser usadas em conjunto em diferentes etapas do ciclo de vida de desenvolvimento de software para garantir a qualidade e a segurança do código. No entanto, em determinadas situações, a análise estática tem uma vantagem clara sobre a dinâmica.
Detecção antecipada de bugs: a análise estática pode ser executada assim que o código é escrito, permitindo detectar e corrigir problemas no início do ciclo de desenvolvimento, antes mesmo do início dos testes. Isso pode economizar muito tempo e reduzir custos.
Cobertura abrangente do código: as ferramentas de análise estática verificam toda a base de código, ao contrário da análise dinâmica, que testa apenas as partes executadas em uma determinada execução.
Aplicação de padrões de programação: as ferramentas de análise estática aplicam padrões de programação e boas práticas. Elas podem ser configuradas para sinalizar desvios, ajudando a manter a consistência e a qualidade do código.
Como usar análise estática em JavaScript
JavaScript, muito usado para criar aplicações web interativas, é uma linguagem dinâmica e de tipagem fraca. Isso significa que as variáveis em JavaScript podem receber valores de qualquer tipo, sem verificação de tipos obrigatória. Essa flexibilidade também pode levar a bugs e vulnerabilidades não detectados.
Por exemplo, veja o seguinte código JavaScript:
function addNumbers(a, b) {
return a+b;
}
console.log(addNumbers(1, 2));
// Outputs: 3
console.log(addNumbers(1, "2"));
// Outputs: "12"No exemplo acima, addNumbers foi criada para somar dois números. No entanto, devido ao sistema de tipos flexível de JavaScript, ela também concatena strings e números, o que provavelmente não é o comportamento esperado. Esse exemplo reforça a importância da análise estática em JavaScript.
Em JavaScript, a análise estática é essencial para manter a segurança do código. Ela pode ajudar a revelar vulnerabilidades ocultas no código que pessoas mal-intencionadas poderiam explorar. Com a importância cada vez maior da cibersegurança, usar ferramentas de análise estática no processo de desenvolvimento é mais uma necessidade do que uma opção.
Como a análise estática melhora a qualidade e a segurança do código JavaScript
Qualidade do código
A análise estática ajuda a aplicar padrões e estilos de programação, deixando o código mais consistente, fácil de ler e de entender. Ela também pode detectar possíveis problemas, como variáveis não utilizadas, código inalcançável e condições redundantes, deixando seu código mais limpo e eficiente.
Por exemplo, veja o seguinte código JavaScript:
let x;
if (x = 10) {
console.log("x is 10");
} else {
console.log("x is not 10");
}Ao executar o ESLint nesse código, você receberá um erro: Expected a conditional expression and instead saw an assignment no-cond-assign
Esse erro ajuda os desenvolvedores a evitar erros comuns, como usar um único sinal de igual para comparar, quando, na verdade, ele é um operador de atribuição.
Segurança do código
As ferramentas de análise estática podem detectar uma ampla variedade de vulnerabilidades de segurança, como ataques de injeção, cross-site scripting (XSS), geração insegura de números aleatórios e outras. Elas permitem verificar essas vulnerabilidades automaticamente, com muito mais eficiência e confiabilidade do que uma revisão manual do código.
Por exemplo, veja o seguinte código Node.js:
const express = require('express');
const Sequelize = require('sequelize');
const access_token = 'a_sample_token';
const app = express();
const sequelize = new Sequelize('database', 'username', 'password', {
dialect: 'sqlite',
storage: 'data/juiceshop.sqlite'
});
app.post('/login', function (req, res) {
sequelize.query('SELECT * FROM Products WHERE name LIKE ' + req.body.username);
});
app.get('/test', function(req,res) {
const test = null;
const dog = test?.dog;
console.log(dog);
});
app.get('/some/path', function(req, res) {
res.redirect(req.param("target"));
});
window.addEventListener("message", (event) => {
console.log(event.data);
});Você consegue encontrar todas as vulnerabilidades aqui?
Felizmente, com o Snyk, essa tarefa é simples. Basta instalar a extensão do Snyk para VS Code no seu IDE para receber feedback em tempo real sobre a segurança do seu código. Depois de salvar o arquivo, os resultados da análise de segurança do Snyk aparecem no editor como em um linter.
Ao executar o Snyk nesse código, você receberá os seguintes avisos:
Injeção de SQL na rota /login
Segredo codificado diretamente no código para uso como token de acesso
Uma vulnerabilidade de redirecionamento aberto na rota /some/path

Na verdade, há mais alguns problemas escondidos. Quer descobrir quais? Crie uma conta gratuita no Snyk e experimente!
Introdução à árvore de sintaxe abstrata (AST)
A árvore de sintaxe abstrata, conhecida como AST (do inglês, Abstract Syntax Tree), é um conceito essencial em programação e segurança de código. Ela pode ser definida como uma representação em árvore da estrutura sintática abstrata do código-fonte escrito em uma linguagem de programação. Cada nó da árvore representa uma construção presente no código-fonte.
Na análise estática de JavaScript, a árvore de sintaxe abstrata tem um papel fundamental. A análise estática examina o código sem executá-lo. É como uma revisão automática do código, que procura possíveis bugs, vulnerabilidades e violações das convenções de programação. As ASTs são essenciais nesse processo porque oferecem uma representação estruturada do código-fonte, mais fácil de percorrer. Com isso, as ferramentas de análise estática podem percorrer o código com mais eficiência e identificar padrões que indiquem bugs ou vulnerabilidades de segurança.
Veja o seguinte código JavaScript:
function greet (name) {
return `Hello, ${name}!`;
}Uma versão simplificada da AST seria assim:
Program
FunctionDeclaration
Identifier (name: greet)
BlockStatement
ReturnStatement
TemplateLiteral
TemplateElement (value: Hello, )
Identifier (name: name)
TemplateElement (value: !)Essa representação ajuda as ferramentas de análise estática a entender a estrutura e o fluxo do código, facilitando a identificação de possíveis problemas.
Como usar o AST Explorer para entender a estrutura do código JavaScript
O AST Explorer é uma ferramenta poderosa que ajuda os desenvolvedores a entender como um trecho de código é transformado em uma árvore de sintaxe abstrata. Compatível com diversas linguagens, incluindo JavaScript, é uma ótima ferramenta para aprender e depurar problemas relacionados a ASTs.
Para usar o AST Explorer com JavaScript, siga estas etapas:
Acesse o AST Explorer.
No menu superior, selecione “JavaScript” como linguagem.
Cole ou escreva código JavaScript no painel à esquerda.
O painel à direita será atualizado automaticamente para exibir a AST do código informado.
Por exemplo, se você inserir a função greet do nosso exemplo anterior:
function greet (name) {
return `Hello, ${name}!`;
}A AST correspondente aparecerá no painel à direita. Ela mostrará a estrutura em árvore do código, que você pode percorrer para entender melhor como ele é interpretado.

Entender ASTs é essencial para dominar a análise estática de JavaScript. Isso oferece informações valiosas sobre a estrutura do seu código, como o mecanismo JavaScript o lê e como as ferramentas de análise estática o interpretam. Com esse conhecimento, você pode escrever código mais eficiente, seguro e livre de bugs.
Três ferramentas de análise estática para JavaScript
As ferramentas de análise estática analisam o código sem executá-lo, daí o termo “estática”. Elas interpretam o código-fonte e criam uma árvore de sintaxe abstrata (AST) para entender sua estrutura e semântica. Em seguida, aplicam diferentes regras e heurísticas à AST para detectar possíveis problemas.
Há várias ferramentas populares de análise estática para JavaScript. A seguir, vamos falar sobre algumas delas.
1. Snyk Code
O Snyk Code é uma ferramenta que você pode usar pela CLI, pelo IDE ou por uma integração com Git para fazer análise estática de segurança. Além dos recursos padrão de análise estática, o Snyk Code oferece análise profunda de código baseada em IA simbólica. Isso permite detectar vulnerabilidades complexas, que envolvem várias etapas e podem passar despercebidas por outras ferramentas.
Veja um exemplo de como a análise estática pode ajudar a identificar um problema de segurança comum: a injeção de SQL. Considere o seguinte trecho de código JavaScript:
let query = "SELECT * FROM users WHERE name = '" + userInput + "'";No código acima, userInput é concatenada diretamente a uma consulta SQL. Se uma pessoa atacante controlar userInput, poderá manipular a consulta para extrair informações confidenciais ou executar ações maliciosas. Uma ferramenta de análise estática como o Snyk pode sinalizar esse padrão como uma possível vulnerabilidade de injeção de SQL.
Para usar o Snyk Code, crie uma conta gratuita no Snyk e instale a Snyk CLI ou use a extensão do Snyk para VS Code para receber feedback em tempo real sobre a segurança do seu código:
npm install -g snyk
snyk auth
snyk testNos comandos acima, instalamos a Snyk CLI, autenticamos com nossa conta Snyk e executamos um teste do Snyk no código.
2. ESLint para análise estática de JavaScript
O ESLint verifica seu código JavaScript em busca de problemas de estilo, possíveis bugs e vulnerabilidades de segurança. Sua arquitetura baseada em plugins permite que os desenvolvedores definam e usem regras personalizadas.
O ESLint analisa padrões no seu código e alerta sobre possíveis problemas que podem causar bugs ou inconsistências, como variáveis não utilizadas, código inalcançável e ponto e vírgula ausente. Para isso, ele interpreta o código e o verifica com base em um conjunto de regras definido por você.
Veja um arquivo básico de configuração .eslintrc.json para o ESLint:
{
"extends": ["eslint:recommended", "plugin:security/recommended"],
"plugins": ["security"],
"rules": {
"security/detect-sql-injection": "warn"
}
}Na configuração acima, usamos as regras recomendadas do ESLint e as regras recomendadas do plugin de segurança. Também ativamos um aviso para possíveis vulnerabilidades de injeção de SQL.
Você pode configurar o ESLint para aplicar uma grande variedade de regras de estilo, incluindo recuo, uso de ponto e vírgula, comprimento das linhas e uso de aspas simples ou duplas em strings. Por exemplo, se preferir um recuo de dois espaços, você pode configurar o ESLint para emitir um aviso sempre que encontrar um código que não siga essa regra.
Além disso, o ESLint ajuda a evitar erros ao alertar você sobre enganos comuns e possíveis problemas no código. Integrar o ESLint ao seu fluxo de desenvolvimento permite encontrar e corrigir erros antes que eles cheguem à produção.
3. Prettier
O Prettier é uma biblioteca JavaScript de código aberto que funciona como um formatador de código com opiniões próprias. Ele ajuda a manter um estilo de programação consistente em toda a base de código ou projeto. Como pessoa desenvolvedora, você talvez já tenha percebido como divergências sobre estilo de código podem desviar a atenção do que realmente importa. O Prettier cuida disso para que você possa se concentrar em escrever código, sem se preocupar com a aparência dele.
O Prettier é compatível com várias linguagens, incluindo JavaScript, TypeScript, CSS, HTML e Markdown, entre outras. Ele se integra à maioria dos editores e funciona imediatamente, sem que você precise perder tempo configurando arquivos complexos. O Prettier analisa seu código e o transforma em uma Árvore Sintática Abstrata (AST), que vimos anteriormente. Em seguida, aplica regras de formatação e gera o código já formatado.
Veja um exemplo de código antes e depois de passar pelo Prettier:
Antes do Prettier:
let foo=function( arg1, arg2 ) {
if (arg1>arg2) {
return arg1
} else {
return arg2
}
}Depois do Prettier:
let foo = function(arg1, arg2) {
if (arg1 > arg2) {
return arg1;
} else {
return arg2;
}
};Como você pode notar, o Prettier padronizou o espaçamento e o posicionamento dos colchetes, além de adicionar um ponto e vírgula ao final das instruções return.
Enquanto o Prettier se concentra exclusivamente na formatação do código, o ESLint verifica padrões no código JavaScript que podem levar a erros. O ESLint é altamente configurável e pode ser ajustado para aplicar padrões e convenções de programação específicos.
É aí que o Prettier e o ESLint se complementam. Enquanto o Prettier garante a formatação consistente do código, o ESLint verifica se ele segue as boas práticas e não contém possíveis bugs. Usar essas duas ferramentas em conjunto pode melhorar muito a qualidade do seu código.
Você pode até configurar o Prettier para formatar o código sempre que salvar um arquivo no editor e deixar o ESLint verificar se há possíveis problemas. Assim, você pode encontrar e corrigir questões antes que elas se tornem problemas.
Veja um exemplo de como configurar isso em um arquivo .eslintrc.json:
{
"plugins": ["prettier"],
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"rules": {
"prettier/prettier": "error"
}
}Nesta configuração, estendemos as regras recomendadas do ESLint e adicionamos o Prettier como plugin. Também definimos a regra prettier/prettier como erro. Isso significa que, sempre que o código não seguir a formatação do Prettier, o ESLint emitirá um erro.
Comece a proteger seus aplicativos JavaScript
Encontre e corrija vulnerabilidades em JavaScript gratuitamente com o Snyk.
Não é necessário informar um cartão de crédito.
Ou cadastre-se com o Azure AD Docker ID Bitbucket
Ao usar o Snyk, você concorda em cumprir nossas políticas, incluindo os Termos de Serviço e a Política de Privacidade.