Segurança de aplicações JavaScript: top 10 vulnerabilidades na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que a segurança de aplicações JavaScript não é uma opção, mas uma necessidade

JavaScript (especialmente na plataforma Node.js) tornou-se a linguagem dominante para criar aplicações tanto do lado do cliente quanto do servidor. No entanto, com o aumento da popularidade, cresce também o número de ataques. De acordo com a OWASP, a maioria das invasões ocorre devido a erros típicos que podem ser prevenidos. Neste artigo, analisaremos o top 10 vulnerabilidades JavaScript (Node.js) com exemplos reais de código e métodos de proteção. O material será útil tanto para desenvolvedores iniciantes quanto experientes que desejam fortalecer a segurança de seus projetos.



1. Injeções (SQL, NoSQL, Command Injection)

As injeções continuam sendo a categoria mais perigosa de vulnerabilidades. No Node.js, MongoDB e PostgreSQL são frequentemente afetados.



Exemplo de código vulnerável (Injeção NoSQL):

// Código vulnerávelapp.post('/login', async (req, res) => {  const { username, password } = req.body;  const user = await db.collection('users').findOne({    username: username,    password: password  });  // Se passar { "username": { "$ne": null }, "password": { "$ne": null } }, retornará o primeiro usuário});


Como corrigir:

  • Use ORM/ODM com parametrização (Mongoose, Sequelize).
  • Valide e sanitize os dados de entrada (biblioteca validator ou joi).
  • Para comandos, use execFile em vez de exec.


2. Cross-Site Scripting (XSS)

XSS permite que um invasor injete um script malicioso na página visualizada por outros usuários.



Exemplo de código vulnerável (XSS Refletido):

// Rota Express vulnerávelapp.get('/search', (req, res) => {  const query = req.query.q;  res.send(`<h1>Resultados da pesquisa para: ${query}</h1>`);  // Se passar ?q=<script>alert('XSS')</script>, o script será executado});


Proteção:

  • Escape a saída: use res.render com mecanismos de template (EJS, Pug) ou encodeURIComponent.
  • Defina o cabeçalho HTTP Content-Security-Policy.
  • Não use innerHTML no cliente — utilize textContent.


3. Autenticação e gerenciamento de sessões inseguros

Autenticação fraca é uma das principais causas de vazamento de dados. Frequentemente, desenvolvedores codificam chaves diretamente no código ou usam senhas fracas.



Erros típicos:

  • Armazenar senhas em texto puro (em vez de bcrypt/argon2).
  • Usar segredos JWT previsíveis (secret123).
  • Ausência de limitação no número de tentativas de login.


Exemplo de implementação correta:

const bcrypt = require('bcrypt');const saltRounds = 12;

app.post('/register', async (req, res) => { const hash = await bcrypt.hash(req.body.password, saltRounds); // Salvar o hash no BD});

app.post('/login', async (req, res) => { const user = await db.getUser(req.body.username); const match = await bcrypt.compare(req.body.password, user.passwordHash); if (match) { // Criar JWT com curto tempo de expiração const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '15m' }); res.json({ token }); }});


4. SSRF (Server-Side Request Forgery)

A vulnerabilidade SSRF permite que um atacante force o servidor a fazer requisições a recursos internos (por exemplo, metadados do provedor de nuvem).



Exemplo:

// Código vulnerável: carregar avatar por URLapp.post('/avatar', async (req, res) => {  const { url } = req.body;  const response = await fetch(url); // Pode passar http://169.254.169.254/latest/meta-data/  // Processar resposta});


Proteção:

  • Crie uma lista de permissões de domínios autorizados.
  • Bloq

Blogs

Book Recommendations