后台管理系统易遭sql注入因其大量动态查询接口常直接拼接用户输入且使用高权限数据库账号,必须对所有用户可控输入(get/post/json/url路径等)强制参数化查询,并针对order by、分页、模糊搜索、导出等高危场景白名单校验或范围限制,同时最小化数据库权限并关闭错误回显。

后台管理系统为什么特别容易被SQL注入
因为后台通常有大量动态查询接口(比如用户搜索、日志筛选、权限批量修改),且开发时容易为“快速上线”直接拼接 username、order_id、status 等参数进 SQL,又常使用高权限数据库账号连接,一旦被攻破,后果比前端接口严重得多。
必须用参数化查询,而不是字符串拼接
所有涉及用户可控输入的 SQL 执行点,包括 GET 查询参数、POST 表单、JSON body、甚至 URL 路径片段(如 /api/users/123 中的 123),都得走参数绑定。
- Java 用
PreparedStatement,别用Statement+String.format或+拼接 - Python(PyMySQL / sqlite3)用
%s或?占位符,不要用f"SELECT * FROM users WHERE id = {user_id}" - PHP(PDO)用
prepare()+execute(),禁用mysql_query()和mysqli_query()直接传参 - Node.js(mysql2)用
pool.execute('SELECT * FROM logs WHERE type = ?', [type]),别用模板字符串
注意:MyBatis 中必须用 #{} ,${} 是字符串替换,等同于拼接,绝对不能用于用户输入字段。
后台管理特有的高危场景要单独加固
这些地方最容易漏防,也是攻击者首选入口:
-
ORDER BY字段名 —— 用户可能传sort=username,但字段名无法参数化,必须白名单校验:if sort not in ['username', 'created_at', 'status']: raise ValueError - 分页
LIMIT参数 ——offset和limit必须转成整数并做范围限制(如max limit=100),防止limit 1,999999999扫库 - 多条件模糊搜索(如 “关键词匹配用户名或邮箱”)—— 不要用
LIKE '%'+kw+'%',改用全文索引或 ES;若必须 LIKE,只允许前缀匹配LIKE ?+'%'并对kw做长度截断(如 ≤50 字符) - 导出 Excel 的查询 —— 后台常为“方便”复用前端搜索逻辑,结果把未过滤的用户输入直接喂给 DAO 层,必须独立走参数化路径
权限和错误信息不能省略
后台系统连库账号权限过大、报错信息泄露表结构,会让一次小漏洞变成全库沦陷:
- 数据库账号只授予
SELECT、UPDATE、INSERT等必要权限,禁用DROP、CREATE、LOAD_FILE、EXECUTE - 关闭数据库错误回显(如 MySQL 的
show_errors=OFF),生产环境 Web 框架也要关掉调试模式,避免把Unknown column 'xxx' in 'where clause'这类信息暴露给前端 - 日志里记录可疑 SQL(如含
UNION SELECT、OR 1=1、SLEEP(的请求),但别记原始参数值,只记脱敏后的哈希或标识
真正难的不是写对一条 prepare,而是确保所有分支路径(尤其是异常处理、导出、批量操作、历史代码遗留接口)都没绕过参数化。后台越“灵活”的功能,越要警惕它背后那条没加问号的 SQL。











