引言:为什么 TypeScript 应用的安全性至关重要
TypeScript 是 JavaScript 的超集,增加了静态类型检查和现代特性。然而,类型检查并不能保证安全性。验证错误、用户输入处理不当以及依赖项中的漏洞都可能导致严重攻击。本文将分析 TypeScript 应用中最常见的十大漏洞,提供代码示例,并展示如何避免它们。
1. 跨站脚本攻击 (XSS)
XSS 攻击发生在攻击者将恶意脚本注入网页时。TypeScript 不会自动防御此类攻击。
漏洞代码示例
function renderUserInput(input: string): string { return `<div>${input}</div>`;}
// 攻击者传入: <script>alert('XSS')</script>解决方案
使用 HTML 字符转义或 DOMPurify 等库:
import DOMPurify from 'dompurify';
function renderUserInputSafe(input: string): string { const sanitized = DOMPurify.sanitize(input); return `<div>${sanitized}</div>`;}2. SQL 注入
如果在 TypeScript 中使用数据库,SQL 查询中不受控制的字符串拼接可能导致数据泄露。
漏洞代码示例
async function getUser(id: string): Promise<User | null> { const query = `SELECT * FROM users WHERE id = '${id}'`; return await db.query(query);}解决方案
使用参数化查询(预编译语句):
async function getUserSafe(id: string): Promise<User | null> { const query = 'SELECT * FROM users WHERE id = $1'; return await db.query(query, [id]);}3. 原型污染
此漏洞常见于 JavaScript/TypeScript。攻击者可以修改对象的原型,从而影响运行时中的所有对象。
漏洞代码示例
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}}'));// 现在所有对象都有 isAdmin: true解决方案
检查键名是否包含危险属性,并使用安全工具:
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. 跨站请求伪造 (CSRF)
CSRF 攻击迫使已认证用户在网站上执行非预期的操作。
TypeScript 解决方案
// 生成 CSRF 令牌import crypto from 'crypto';
function generateCsrfToken(): string { return crypto.randomBytes(32).toString('hex');}
// 在中间件中验证function 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. 不安全的反序列化
对未经验证的数据使用 JSON.parse() 或 eval() 可能导致任意代码执行。
漏洞示例
function processData(data: string) { const obj = eval('(' + data + ')'); // ...}安全方法
function processDataSafe(data: string) { try { const obj = JSON.parse(data); // 额外类型验证 if (typeof obj !== 'object' || obj === null)