最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何利用标记模板字符串(Tagged Templates)防御 SQL 注入与 XSS
时间:2026-08-04 09:58:49 编辑:袖梨 来源:一聚教程网
如何利用标记模板字符串(Tagged Templates)防御 SQL 注入与 XSS需要先看清适用场景和关键步骤,避免只记结论却忽略实际限制。
模板字符串本身不防SQL/XSS,因${}仅作字符串拼接无转义;真正安全需自定义标签函数,如sql...${x}...生成?占位符与参数数组交由驱动执行。
为什么 String.raw 或普通模板字符串本身不防 SQL/XSS
很多人误以为用了模板字符串就“天然安全”,其实完全相反:`SELECT * FROM users WHERE id = ${id}` 和拼接字符串一样危险。JavaScript 模板字符串只是语法糖,${} 里的值会直接转成字符串并插入,没有任何转义或上下文感知。SQL 注入和 XSS 的本质是“数据被当成了代码执行”,而模板字符串根本不区分数据与代码——它只负责拼。
Tagged Templates 怎么介入并起作用
真正起作用的是标签函数(tag function),它能拦截模板字面量和插值参数,拿到原始字符串数组和动态值,从而在拼接前做上下文相关的处理。关键点在于:你必须自己写/用可靠的标签函数,且它得知道当前目标是 SQL 还是 HTML。
- SQL 场景下,标签函数要对每个插值参数做参数化处理(如转成
?占位符),再把值单独传给数据库驱动,绝不能拼进字符串 - HTML 场景下,标签函数要对每个插值做 HTML 实体编码(如
&→&),但注意:不能编码整个模板字符串,否则破坏结构;只编码插值部分 - 标签函数无法自动识别意图——
sql`...${x}...`和html`<div>${x}</div>`的区别全靠函数名和实现逻辑,不是语法强制的
实际可用的标签函数怎么写(以 SQL 为例)
下面这个 sql 标签函数不执行查询,只生成带 ? 占位符的语句和参数数组,交由底层驱动(如 mysql2、pg)安全执行:
function sql(parts, ...values) { let query = parts[0]; const params = []; for (let i = 0; i < values.length; i++) { query += '?' + parts[i + 1]; params.push(values[i]); } return { text: query, params };}<p>// 使用示例const id = "1; DROP TABLE users; --";const result = sql<code>SELECT * FROM users WHERE id = ${id} AND active = ${true}</code>;// → { text: "SELECT * FROM users WHERE id = ? AND active = ?", params: ["1; DROP TABLE users; --", true] }
注意:result 不能直接传给 exec(),必须交给支持参数化查询的驱动。若你硬用 eval() 或字符串拼接去“执行” result.text,等于白做。
常见陷阱和不可替代的前提
Tagged Templates 不是银弹。最容易被忽略的几点:
- 你写的标签函数如果内部调用了
String(value)再拼进 SQL 字符串,就立刻失效——必须坚持参数分离,绝不拼值 - HTML 场景下,如果插值本身是已信任的 HTML 片段(比如组件返回的
<span>OK</span>),用html标签函数会把它双编码成<span>OK</span>,反而显示为源码。这时需要显式标记“已信任”,例如html`<div>${raw(trustedHtml)}</div>` - 所有插值都必须走标签函数路径。漏掉一个
${userInput}没包在sql``或html``里,整条链就破了 - 后端模板引擎(如 EJS、Nunjucks)的插值语法(
)和 JS Tagged Templates 无关,别混用
真正的防线不在语法糖,而在是否始终把数据和代码的边界守死——Tagged Templates 只是帮你把这道边界显式地写在调用处。
相关文章
- 鹅鸭杀超级金水铃模式怎么玩 08-07
- 牧场物语风之繁华集市生日日期怎么看 08-07
- 口袋新旅途如何捕捉颓颓鹰 08-07
- DNF狄瑞吉版本女漫游加点攻略 08-07
- 鹅鸭杀士兵怎么玩 08-07
- DNF狄瑞吉版本协战师加点攻略 08-07