讲师中心 微信公众号
AI工具推荐 视频效率加速

为什么LIMIT分页参数也会引发SQL注入以及如何防范

浅伟君_4826

浅伟君_4826

发布时间:2026-10-20 08:21:33

|

600人浏览过

|

来源于php中文网

原创

仅对 LIMIT 和 OFFSET 做 int 强制转换无法防御 SQL 注入,因数据库协议中 LIMIT 值属语法结构而非数据值,且存在多语句、类型混淆、驱动未启用服务端预编译、ORDER BY 字段注入等绕过路径。

为什么limit分页参数也会引发sql注入以及如何防范

仅对 LIMIT 和 OFFSET 参数做 int 强制转换,不能防 SQL 注入。它只拦得住最表层的字符串拼接,但挡不住多语句、类型混淆、驱动未启用预编译、或与 ORDER BY ${sortField} 联动等真实攻击路径。

为什么 LIMIT 后面的数字也能被注入

因为数据库协议本身不支持把 LIMIT 的值当作参数绑定——它属于语法结构,不是数据值。MySQL 5.7+ 虽然支持 LIMIT ? OFFSET ?,但前提是 JDBC 连接串必须显式开启 useServerPrepStmts=true;否则驱动会在客户端把 ? 拼成字符串,预编译完全失效。

  • 攻击者传 10; DROP TABLE users--,若数据库连接允许多语句(allowMultiQueries=true),真会执行删表
  • 传 1e2、0x14、-1 或超大数如 9999999999999999999,部分 ORM 或旧驱动未严格校验就透传,导致整数溢出或全表扫描
  • OFFSET 常和用户可控的排序字段耦合,比如 ORDER BY ${sortField} LIMIT ? OFFSET ?,即使 OFFSET 是 int,sortField 若没白名单,就能注入子查询:id, (SELECT password FROM users LIMIT 1)

Java JDBC 中正确使用 PreparedStatement 绑定 LIMIT/OFFSET

必须同时满足三个条件:SQL 模板用 ? 占位、驱动启用服务端预编译、参数在 setInt() 前完成范围校验。

  • JDBC URL 加上 ?useServerPrepStmts=true&cachePrepStmts=true,否则 LIMIT ? 会被客户端拼接
  • SQL 写成 "SELECT * FROM orders WHERE status = ? ORDER BY created_at DESC LIMIT ? OFFSET ?",不能含任何字符串拼接
  • ps.setInt(2, size) 前必须校验:size > 0 && size <= 100;ps.setInt(3, offset) 前校验:offset >= 0 && offset <= 1000000
  • 校验失败直接返回 400,不 fallback 到默认值(比如 offset=0)——fallback 会掩盖非法输入,给攻击者试探空间

MyBatis 中禁用 ${},只用 #{} 处理分页参数

${} 是字符串替换,无论里面是不是数字都会拼进 SQL;#{} 才走预编译。但要注意:MyBatis 的 #{} 对 LIMIT 的支持依赖底层驱动是否启用服务端预编译,不是写对了就一定安全。

  • XML 映射中必须写 LIMIT #{size} OFFSET #{offset},绝不能出现 LIMIT ${size}
  • Mapper 方法参数必须是基本类型或包装类(如 Integer),不能是 Map<String, Object> 或泛型对象——后者可能触发 MyBatis 回退到字符串拼接
  • MyBatis-Plus 的 Page<T> 对象本身安全,但自定义 SQL 里如果手写了 LIMIT #{size},仍要确认运行时是否真调用了 PreparedStatement.setInt()
  • ORDER BY 字段无法参数化,只能硬编码白名单:if (!Arrays.asList("id", "created_at", "status").contains(sortField)) throw new IllegalArgumentException();

所有语言都必须先正则校验再强转,不能只靠 parseInt/int()

很多语言的 parseInt("10abc") 返回 10,int(" 10 ") 在 Python 中成功但隐含空格风险——这些都会绕过“看起来是数字”的表层防护。

  • 原始字符串必须先用正则 ^[0-9]+$ 校验:不允许负号、小数点、空格、前导零、科学计数法
  • 再用语言原生强转函数:Integer.parseInt()(Java)、int()(Python)、strconv.Atoi()(Go)、Number() + isFinite() + Number.isInteger()(Node.js)
  • 立即检查范围:limit 通常限制在 1–1000,offset 上限建议设为 100000(防深度翻页 DoS)
  • 任一环节失败,HTTP 状态码 400 返回,不设默认值,不记录日志后继续执行

真正难的不是写对 ps.setInt(1, size),而是确保从请求解析、参数提取、类型转换、范围校验、SQL 构造、驱动执行,整条链路上每个用户可控点(分页、排序、搜索、过滤)都遵循同一套校验和传参规则——漏掉任意一环,防护就形同虚设。

热门AI工具

更多
讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4383

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

911

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1149

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6301

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3123

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6280

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

8521

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1150

2024.04.29

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

80

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP开发基础之数据库篇(PDO)
PHP开发基础之数据库篇(PDO)

共10课时 | 2.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn