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

Express服务器提交‘1 or 1=1’无响应问题排查求助

问题分析与解决方案

核心原因

提交1 or 1=1时服务器无响应,本质是异步SQL查询卡住且未被捕获错误,导致请求处理流程停滞:

  • 代码直接拼接用户输入生成SQL语句,当输入包含or 1=1这类内容时,会生成恶意查询(比如SELECT * FROM web_user WHERE user=1 or 1=1 AND password=xxx)。如果mysql.validateString没有正确转义SQL特殊字符,数据库会执行这个异常查询,可能陷入全表扫描或语法错误,导致await systemdb.query的Promise一直处于pending状态。
  • 异步中间件和路由中没有错误捕获逻辑,一旦query抛出错误或卡住,错误会被静默吞掉,请求得不到响应,也不会输出日志。
  • 你添加的app.post("*")没触发,是因为请求还卡在前面的app.use中间件里(中间件的await systemdb.query没完成,next()没执行),根本没走到后续路由。

修复步骤

1. 彻底替换为参数化查询(必做)

直接拼接用户输入是SQL注入的高危操作,必须改用参数化查询,避免恶意SQL生成:

// 登录接口修改示例
app.post('/login', async (req, res) => {
  cubing.info("post login")
  try {
    // 用参数化查询代替字符串拼接
    const result = await systemdb.query(
      'SELECT * FROM web_user WHERE user = ? AND password = ?',
      [req.body.username, req.body.password]
    )
    if (result.length > 0) {
      const token = uuid.v4()
      // 更新token也用参数化
      await systemdb.query(
        "UPDATE web_user SET token = ? WHERE user = ? AND password = ?",
        [token, req.body.username, req.body.password]
      )
      res.cookie('login', { token: token }, { httpOnly: false })
      res.redirect('/')
    } else {
      res.render('login.ejs', {
        loginName: req.loginName,
        error: true,
      })
    }
  } catch (err) {
    cubing.error('Login query error:', err)
    res.status(500).send('Server error')
  }
})

同时修改中间件里的token查询:

// 中间件中的token验证
const result = await systemdb.query(
  "SELECT user,admin FROM web_user WHERE token = ?",
  [req.cookies.login.token]
)

2. 给所有异步操作添加错误捕获

在async中间件和路由中用try/catch包裹异步代码,避免错误静默丢失:

// 全局中间件修改
app.use(async (req, res, next) => {
  cubing.info("use")
  let redir = false
  try {
    // ... 原重定向逻辑 ...
    if (redir) {
      res.redirect('https://speedcubing.top' + req.url)
    } else {
      if (req.url != 'myip') {
        req.loginName = ''
        req.admin = false
        if (req.cookies.login !== undefined) {
          const result = await systemdb.query(
            "SELECT user,admin FROM web_user WHERE token = ?",
            [req.cookies.login.token]
          )
          if (result.length > 0) {
            req.loginName = result[0].user
            req.admin = result[0].admin.lastIndexOf(1) !== -1
          }
        }
      }
      next()
    }
  } catch (err) {
    cubing.error('Middleware error:', err)
    res.status(500).send('Server error')
    // 不要调用next(),避免后续逻辑执行
  }
})

3. 检查并修正mysql.validateString(可选)

如果这个函数的作用是转义SQL字符,确保它能正确处理单引号、双引号、关键字等;如果它只是简单过滤,直接弃用即可——参数化查询已经足够安全。

4. 给数据库查询添加超时

在你的SQL.js中配置查询超时,防止异常查询长时间卡住:

// 示例:在创建数据库连接时设置超时
const connection = mysql.createConnection({
  host: host,
  user: user,
  password: pass,
  connectTimeout: 5000,
  acquireTimeout: 5000,
  timeout: 5000
})

验证

修改后提交1 or 1=1,会被参数化查询当作普通字符串处理,不会生成恶意SQL;同时如果出现错误会被捕获并输出日志,请求不会再无响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:25:23