Introdução: por que a segurança de aplicações TypeScript é importante desde o primeiro dia
TypeScript é uma extensão do JavaScript que adiciona tipagem estática. Muitos desenvolvedores iniciantes acreditam erroneamente que a tipagem resolve automaticamente todos os problemas de segurança. Na verdade, o TypeScript é compilado para JavaScript comum, e todas as vulnerabilidades inerentes ao JS permanecem relevantes. Neste artigo, vamos analisar as 10 principais vulnerabilidades que os iniciantes enfrentam e mostrar como evitá-las.
1. XSS (Cross-Site Scripting)
XSS é um dos ataques mais comuns. O invasor insere um script malicioso na página, que é executado no navegador do usuário.
Exemplo de código vulnerável:
function renderUserInput(input: string): string { return `<div>${input}</div>`;}
// O invasor envia: <script>alert('XSS')</script>Como corrigir:
Sempre escape a entrada do usuário. Use bibliotecas como DOMPurify ou métodos de escape embutidos:
import DOMPurify from 'dompurify';
function safeRender(input: string): string { const clean = DOMPurify.sanitize(input); return `<div>${clean}</div>`;}2. Injeção de SQL
Se você estiver construindo consultas SQL concatenando strings com entrada do usuário, estará abrindo a porta para injeção de SQL.
Código vulnerável:
function getUser(username: string): Promise<User> { const query = `SELECT * FROM users WHERE username = '${username}'`; return db.execute(query);}Versão segura:
function getUserSafe(username: string): Promise<User> { const query = 'SELECT * FROM users WHERE username = $1'; return db.execute(query, [username]); // consulta parametrizada}3. Armazenamento inseguro de senhas
Nunca armazene senhas em texto simples. Use bcrypt ou argon2 para hash.
import bcrypt from 'bcrypt';
async function hashPassword(password: string): Promise<string> { const saltRounds = 12; return bcrypt.hash(password, saltRounds);}
async function verifyPassword(password: string, hash: string): Promise<boolean> { return bcrypt.compare(password, hash);}4. Referências diretas inseguras a objetos (IDOR)
Quando um usuário pode acessar dados de outros usuários simplesmente alterando o ID na URL.
Exemplo:
// Vulnerável: qualquer usuário pode obter qualquer pedidoapp.get('/api/order/:id', (req, res) => { const order = getOrderById(req.params.id); res.json(order);});
// Seguro: verificamos a propriedadeapp.get('/api/order/:id', (req, res) => { const order = getOrderById(req.params.id); if (order.userId !== req.user.id) { return res.status(403).json({ error: 'Forbidden' }); } res.json(order);});5. Uso de dependências desatualizadas
Projetos TypeScript frequentemente usam pacotes npm. Versões desatualizadas podem conter vulnerabilidades conhecidas.
- Execute regularmente
npm audit - Use
npm updatepara atualizar pacotes - Configure verificações automáticas no CI/CD
6. Validação insuficiente de dados de entrada
Os tipos do TypeScript não são verificados em tempo de execução. Sempre valide os dados no servidor.
interface UserInput { email: string; age: number;}
// Insuficiente: os tipos do TypeScript não protegem em tempo de execuçãofunction processUser(input: UserInput) { // ...}
// Correto: use Zod ou Joi para validaçãoimport { z } from 'zod';
const UserSchema = z.object({ email: z.string().email(), age: z.number().min(18).max(120)});
function processUserSafe(input: unknown) { const validate
```