输入单/双引号导致Node+Express+sqlite3应用崩溃问题求助
问题根因
1. 首次输入特殊字符崩溃的原因
当前代码直接将用户输入拼接进SQL语句,输入'这类SQL保留字符时,会直接破坏SQL语法结构,产生非法查询语句,数据库执行时会抛出错误。但代码中db.all的回调逻辑完全没有对error参数做判断,无论查询是否成功都直接将rows传递给模板渲染,此时rows为undefined,模板中执行data.forEach时会直接抛出类型错误,导致页面渲染失败。
2. 后续正常输入仍崩溃的原因
最常见的两类情况:
- Express服务没有配置全局错误捕获中间件,首次未处理的渲染错误会导致Node进程直接退出或进入挂起状态,无法响应后续所有请求
- sqlite3的数据库连接实例在抛出未处理的SQL错误后进入异常锁定状态,后续所有查询请求都会被阻塞无法执行
修复方案
1. 改用参数化查询,避免SQL语法错误与注入风险
不要直接拼接SQL字符串,使用sqlite3支持的参数占位符处理用户输入,框架会自动转义特殊字符:
// app.js 修正后的查询逻辑 const query = "SELECT * FROM tab WHERE name = ?" db.all(query, [req.query.name], (error, rows) => { // 新增错误处理逻辑 if (error) { // 出错时传入空数组避免模板遍历报错,同时返回错误提示 return res.render(__dirname + '/views/search.ejs', { data: [], msg: `查询失败:${error.message}` }) } // 正常查询逻辑保持不变 res.render(__dirname + '/views/search.ejs', {data:rows, msg:req.query.name + " is available!"}) })
2. 新增Express全局错误捕获中间件
在所有路由逻辑的末尾添加如下代码,避免单请求错误导致整个服务崩溃:
app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('服务暂时异常,请稍后重试') })
3. 修复模板XSS漏洞
当前search.ejs中使用<%- %>输出msg内容,会直接解析用户输入的HTML标签,存在跨站脚本攻击风险,修改为自动转义的输出语法:
<!-- 将 <span><%- msg %></span> 替换为 --> <span><%= msg %></span>
内容的提问来源于stack exchange,提问作者seriouslyg0e
相关产品推荐
相关产品推荐

