玩家名字是玩家说了算的输入:注册一个名叫 裁决'; DELETE FROM roles;-- 的角色,拼接式 SQL 立刻变成别人的武器。SQL 注入的防线只有一条正道——参数化查询,所有用户输入永远当数据不当代码。
---危险写法:字符串拼接 SQL
-- local sql = "SELECT * FROM roles WHERE name = '" .. name .. "'"
---参数化写法:占位符加参数绑定
function Role.findByName(name)
local rows = DB.query("SELECT * FROM roles WHERE name = ?", name)
return rows[1]
end
---模糊查询的参数化:通配符转义
function Role.search(kw)
kw = "%" .. kw:gsub("([%%_])", "\\%1") .. "%"
return DB.query(
"SELECT name, level FROM roles WHERE name LIKE ? ESCAPE '\\'", kw)
end
拼接式 SQL 把输入升格成了代码,参数化把输入永远锁在数据的牢笼里:占位符加绑定值,数据库驱动负责转义,任何引号与分号都只是字符。模糊查询的参数化多一步通配符转义——玩家输入的百分号与下划线在 LIKE 里有特殊含义,转义后按字面匹配,搜索"100%胜率"不会变成全表通配。
---输入的合法性前置校验
local NAME_PATTERN = "^[%w%p]+$"
function Role.validateName(name)
if #name < 2 or #name > 16 then
return false, "名字长度须在 2 到 16 个字符"
end
if not name:match(NAME_PATTERN) then
return false, "名字含非法字符"
end
local banned = { [";"] = true, ["'"] = true, ["--"] = true }
for k in pairs(banned) do
if name:find(k, 1, true) then
return false, "名字含非法字符"
end
end
return true
end
参数化是主防线,输入校验是纵深:角色名的长度 2 到 16、白名单字符集、分号与注释符的黑名单,非法名字在注册口就被拒。纵深不替代参数化——校验挡得住注册口挡得住所有入口吗,任何一处遗漏的拼接都是突破口,主防线不许打折。代码评审的检查项:SQL 拼接一律打回,DB 层封装只暴露参数化接口,拼接的写法在代码库里无法存活。
注入用例进回归测试:典型载荷(引号闭合、注释截断、UNION 拼接)逐条打一遍,全部参数化挡下;DB 层的慢日志与异常 SQL 告警,非参数化的调用在日志里无处遁形。
表名与列名的动态拼接曾经被忽视,排序字段直接拼进 ORDER BY,注入面从值转移到标识符,白名单枚举合法列名。LIKE 的转义字符曾经没配 ESCAPE 子句,反斜杠转义不生效,通配符仍然越界。报错信息曾经原样回显 SQL 异常,注入者拿报错当探针,错误统一吞掉换通用文案。
DB 访问层的参数化是唯一入口,原始 exec 的调用权限收敛到一个人。新人的第一次 SQL 审查是必修课,注入的用例库随攻击手法的演进而更新。数据库账号的最小权限:游戏账号不给 DROP 与 FILE 权限,防线的纵深处还有一层。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 盟重矿洞挖出的黑曜石除了堆仓库没有去向,矿工玩法缺一条消耗链。黑市商人每 4 小时换一批限时货架,6 个…
实战应用:用在哪里 盟重码头到沙巴克水路要 20 分钟,商船运货收益高但会被半兽海盗打劫,单人押船九死一生。码头护航做成对抗…
实战应用:用在哪里 拍卖行竞拍高峰,一件屠龙刀 1 秒能产生 60 条竞价事件,逐条 sendluamsg 下发,竞拍面板每…
实战应用:用在哪里 金盒转盘 8 格奖池,普通奖越来越疲,大奖既要概率递增又不能失控。动态权重轮盘:每抽一次普通奖权重缩减 …
实战应用:用在哪里 周年庆礼包开领 30 分钟,3000 名玩家多领了一份礼盒,回收与舆情处理耗掉两天。事故根因简单得刺眼:…
实战应用:用在哪里 一次回档让玩家的裁决之杖从强化 7 退回 5,口头承诺补偿却没有账可查。强化流水把每次强化的时间、道具、…