Introduction : pourquoi la sécurité des applications TypeScript est cruciale
TypeScript est une surcouche de JavaScript qui ajoute un typage statique et des fonctionnalités modernes. Cependant, le typage ne garantit pas la sécurité. Les erreurs de validation, le traitement incorrect des entrées utilisateur et les vulnérabilités dans les dépendances peuvent entraîner des attaques graves. Dans cet article, nous allons analyser le top 10 des vulnérabilités les plus courantes des applications TypeScript, fournir des exemples de code et montrer comment les éviter.
1. Cross-Site Scripting (XSS)
Les attaques XSS se produisent lorsqu'un attaquant injecte un script malveillant dans une page web. TypeScript ne protège pas automatiquement contre cela.
Exemple de code vulnérable
function renderUserInput(input: string): string { return `<div>${input}</div>`;}
// L'attaquant transmet : <script>alert('XSS')</script>Solution
Utilisez l'échappement des caractères HTML ou des bibliothèques comme DOMPurify :
import DOMPurify from 'dompurify';
function renderUserInputSafe(input: string): string { const sanitized = DOMPurify.sanitize(input); return `<div>${sanitized}</div>`;}2. Injections SQL
Si vous utilisez TypeScript avec des bases de données, la concaténation non contrôlée de chaînes dans les requêtes SQL peut entraîner une fuite de données.
Exemple de code vulnérable
async function getUser(id: string): Promise<User | null> { const query = `SELECT * FROM users WHERE id = '${id}'`; return await db.query(query);}Solution
Utilisez des requêtes paramétrées (prepared statements) :
async function getUserSafe(id: string): Promise<User | null> { const query = 'SELECT * FROM users WHERE id = $1'; return await db.query(query, [id]);}3. Pollution de prototype (Prototype Pollution)
Cette vulnérabilité est caractéristique de JavaScript/TypeScript. Un attaquant peut modifier le prototype d'un objet, ce qui affecte tous les objets à l'exécution.
Exemple de code vulnérable
function merge(target: any, source: any) { for (const key in source) { if (source.hasOwnProperty(key)) { target[key] = source[key]; } }}
const user = { name: 'Alice' };merge(user, JSON.parse('{"__proto__": {"isAdmin": true}}'));// Désormais, tous les objets ont isAdmin: trueSolution
Vérifiez les clés pour les propriétés dangereuses et utilisez des utilitaires sécurisés :
function safeMerge(target: Record<string, any>, source: Record<string, any>) { for (const key in source) { if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue; target[key] = source[key]; }}4. Cross-Site Request Forgery (CSRF)
Les attaques CSRF forcent un utilisateur à effectuer des actions non désirées sur un site où il est authentifié.
Solution en TypeScript
// Génération d'un token CSRFimport crypto from 'crypto';
function generateCsrfToken(): string { return crypto.randomBytes(32).toString('hex');}
// Vérification dans le middlewarefunction csrfMiddleware(req: Request, res: Response, next: NextFunction) { const token = req.headers['x-csrf-token']; if (token !== req.session.csrfToken) { return res.status(403).json({ error: 'CSRF validation failed' }); } next();}5. Déserialisation non sécurisée
L'utilisation de JSON.parse() ou eval() sur des données non vérifiées peut entraîner l'exécution de code arbitraire.
Exemple vulnérable
function processData(data: string) { const obj = eval('(' + data + ')'); // ...}Approche sécurisée
function processDataSafe(data: string) { try { const obj = JSON.parse(data); // Validation supplémentaire du type if (typeof obj !== 'object' || obj === null)