Seu código na mira: por que a segurança TypeScript não é uma opção, mas uma necessidade
\n\nVocê já parou para pensar no que acontece quando um usuário digita no campo de busca do seu site não apenas "livros de Python", mas algo como '; DROP TABLE users; --? Se seu backend em TypeScript não estiver preparado para essa situação, você corre o risco não apenas de receber um erro, mas de perder todo o banco de dados. Parece um roteiro de filme de terror? Bem-vindo ao mundo real do desenvolvimento web, onde a segurança TypeScript não é um recurso da moda, mas uma higiene básica de código.
Neste artigo, não vamos dar palestras chatas. Vamos analisar os dois principais inimigos de qualquer aplicação web: injeções SQL e XSS (Cross-Site Scripting). Você aprenderá como os hackers atacam seus projetos e, o mais importante, como transformar seu código TypeScript em uma fortaleza inexpugnável com exemplos reais e melhores práticas.
\n\nInjeções SQL: como os invasores "conversam" com seu banco de dados
\n\nImagine que sua aplicação é um porteiro educado que atende a qualquer pedido de um hóspede. Se o hóspede pedir: "Mostre o quarto nº 5", o porteiro mostra. Mas e se o hóspede pedir: "Mostre todos os quartos e me dê as chaves do cofre"? Sem verificação, o porteiro também faria isso. A injeção SQL funciona exatamente assim: o invasor "insere" seus comandos em uma entrada de usuário comum.
\n\nSuponha que você tenha uma consulta simples para buscar um usuário pelo nome:
\n\n// ❌ PERIGOSO: código vulnerável\nconst userName = req.body.username; // usuário digitou "admin"\nconst query = `SELECT * FROM users WHERE name = '${userName}'`;\ndb.execute(query);\n\nParece inofensivo? Agora imagine que o usuário digita: admin' OR '1'='1. A consulta se transforma em:
SELECT * FROM users WHERE name = 'admin' OR '1'='1'\n\nParabéns! Você acabou de entregar ao invasor a lista de todos os usuários do sistema. E se ele quiser excluir algo? Fácil: admin'; DROP TABLE users; -- — e seu banco de dados não existe mais.
Como se proteger: consultas parametrizadas — seu escudo
\n\nA regra principal para proteção contra injeções SQL em TypeScript: nunca insira dados do usuário diretamente em uma string de consulta. Use consultas parametrizadas (prepared statements). Elas separam o código SQL dos dados, e o banco de dados trata a entrada do usuário exclusivamente como dados, e não como comandos.
\n\nExemplo com a biblioteca pg (para PostgreSQL):
// ✅ SEGURO: consulta parametrizada\nimport { Pool } from 'pg';\n\nconst pool = new Pool({\n connectionString: process.env.DATABASE_URL\n});\n\nasync function getUserByName(userName: string): Promise<any> {\n const query = 'SELECT * FROM users WHERE name = $1';\n const result = await pool.query(query, [userName]);\n return result.rows;\n}\n\n// Uso\nconst userInput = req.body.username; // mesmo que seja "admin' OR '1'='1"\nconst user = await getUserByName(userInput);\n// O banco de dados tratará isso como uma busca por um usuário com esse nome estranho\nconsole.log(user); // [] — nada encontrado\n\nO mesmo princípio funciona com outros ORMs, como Prisma ou TypeORM. Eles usam consultas parametrizadas por padrão, tornando a segurança TypeScript uma funcionalidade incorporada.
\n\n// ✅ SEGURO: usando Prisma\nimport { PrismaClient } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nasync function findUser(name: string) {\n return prisma.user.findUnique({\n where: { name: name } // Prisma escapa os dados de entrada automaticamente\n });\n}\n\nAtaques XSS: quando seu site começa a transmitir código de terceiros
\n\nSe as injeções SQL atingem o banco de dados, o XSS (Cross-Site Scripting) ataca seus usuários. Imagine que um invasor