You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用预准备语句替换存在注入风险的字符串插值代码?

安全重写方案(无需预定义字段列表)

你的代码存在两处SQL注入风险:直接拼接tablename(作为查询值)和attributeId(作为JSON键与字段别名)。除了预定义字段列表,我们可以利用PostgreSQL官方驱动的转义工具+参数化查询来低成本解决问题:

核心思路

  1. 值类型参数(如tablename):用参数化查询处理,这是处理值类型参数最安全的方式,完全避免字符串拼接带来的注入风险。
  2. JSON键(字符串字面量):用pg库的escapeLiteral方法转义,确保单引号、特殊字符不会破坏SQL语句结构。
  3. 字段别名(标识符):用pg库的escapeIdentifier方法转义,处理包含特殊字符、SQL关键字的字段名场景。

重写后的代码

const { escapeLiteral, escapeIdentifier } = require('pg');
const { tablename, attributeId } = req.params;
let stmt;
let result;

// 对JSON键和别名分别做安全转义
const escapedAttrKey = escapeLiteral(attributeId);
const escapedAttrAlias = escapeIdentifier(attributeId);

// 构造SQL:source用参数化占位符$1
stmt = `SELECT DISTINCT row_data->>${escapedAttrKey} AS ${escapedAttrAlias} FROM csv_data WHERE source = $1`;

try {
  // 执行时传入参数数组,驱动自动处理值的安全注入
  result = await pool.query(stmt, [tablename]);
} catch (err) {
  console.error(err);
}

// ... 后续逻辑保持不变
return res.status(200).json({
  rows: result.rows.map(elt => elt[attributeId]),
  rowCount: result.rowCount,
});

安全原理说明

  • escapeLiteral会自动转义字符串中的单引号、反斜杠等特殊字符,确保JSON键的字符串字面量不会被篡改注入。
  • escapeIdentifier会将标识符用双引号包裹,即使字段名包含空格、SQL关键字(如select),也能被数据库正确识别为字段别名。
  • 参数化查询($1)由数据库驱动自动处理值的转义,彻底杜绝值类型的SQL注入。

额外优化建议

如果想进一步降低风险,可以给attributeId加简单格式校验(比如禁止空字符、控制字符),但这比维护预定义字段列表的成本低得多。

内容的提问来源于stack exchange,提问作者Dycey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 23:27:20