TypeScript 应用安全:十大常见漏洞实战解析

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

TypeScript 应用安全:十大常见漏洞实战解析



TypeScript 是 JavaScript 的超集,增加了静态类型检查。许多开发者错误地认为强类型会自动使应用变得安全。事实并非如此。TypeScript 编译器会检查类型,但无法防御逻辑错误、注入攻击或认证问题。在本文中,我们将分析 TypeScript 应用中最常见的 10 个漏洞,展示代码示例,并提供具体的防护建议。无论您是初学者还是经验丰富的开发者,本文都将对您有所帮助。



1. 因输入处理不当导致的跨站脚本攻击 (XSS)



XSS 仍然是最危险的漏洞之一。TypeScript 不会自动转义输出。如果您将用户数据直接插入 HTML 模板而不进行清理,就等于为攻击敞开了大门。



存在漏洞的代码

function renderComment(comment: string): string {  return `<div>${comment}</div>`;}

// 攻击者传入:<script>alert('XSS')</script>


修复后的代码

import { escape } from 'lodash';

function renderComment(comment: string): string { const safeComment = escape(comment); return `<div>${safeComment}</div>`;}


建议:始终使用转义库(如 DOMPurify、lodash.escape)或具有自动转义功能的模板引擎(如 React JSX、Handlebars)。



2. 通过字符串模板导致的 SQL 注入



TypeScript 允许使用模板字符串构建 SQL 查询。如果您直接拼接用户数据,这将是 SQL 注入的直接途径。



存在漏洞的代码

async function getUser(id: string): Promise<User | null> {  const query = `SELECT * FROM users WHERE id = '${id}'`;  const result = await db.query(query);  return result.rows[0];}


修复后的代码

async function getUser(id: string): Promise<User | null> {  const query = 'SELECT * FROM users WHERE id = $1';  const result = await db.query(query, [id]);  return result.rows[0];}


建议:使用参数化查询或 ORM(如 TypeORM、Prisma、Sequelize)。切勿拼接 SQL 字符串。



3. 不安全的密码比较



密码比较实现中的错误可能导致时序攻击。TypeScript 开发者经常使用 === 运算符比较哈希值,这是不安全的。



存在漏洞的代码

async function verifyPassword(  inputPassword: string,   storedHash: string): Promise<boolean> {  const inputHash = await bcrypt.hash(inputPassword, 10);  return inputHash === storedHash; // 漏洞:时序攻击}


修复后的代码

import bcrypt from 'bcrypt';

async function verifyPassword( inputPassword: string, storedHash: string): Promise<boolean> { return bcrypt.compare(inputPassword, storedHash);}


建议:使用哈希库(如 bcrypt.compare、argon2.verify)内置的比较函数。它们能防御时序攻击。



4. 通过递归合并对象导致的原型污染



TypeScript 应用经常使用深度拷贝或对象合并函数。如果不控制键名,攻击者可能会污染 Object.prototype 原型。



存在漏洞的代码

function merge(target: Record<string, any>, source: Record<string, any>) {  for (const key in source) {    if (typeof source[key] === 'object') {      target[key] = merge(target[key] || {}, source[key]);    } else {      target[key] = source[key];    }  }  return target;}

// 攻击者传

博客

书籍推荐