怎样在JSP页面中通过标签库防御SQL注入_使用c:out与sql:param标签

秋浩酱_3556

秋浩酱_3556

2026-05-26

429人浏览

原创

c:out 不能防 SQL 注入,因为它仅做 HTML 转义、不影响 SQL 构建;防注入必须用 sql:param 实现参数化查询,但 JSTL SQL 标签库已不推荐用于生产,应改用 PreparedStatement 或 MyBatis 等框架。

怎样在jsp页面中通过标签库防御sql注入_使用c:out与sql:param标签

为什么 c:out 不能防 SQL 注入

c:out 只做 HTML 转义,把 变成 ,防止 XSS,对 SQL 查询毫无作用。如果你在 JSP 里写 SELECT * FROM user WHERE name = '${param.name}',再套一层 ,照样被注入——因为 c:out 根本不参与 SQL 构建过程。

常见错误现象:页面显示内容“安全”了,但数据库被删表、拖库、报错 java.sql.SQLException: ORA-00933: SQL command not properly ended。

  • c:out 是 JSTL 输出标签,只影响响应体的 HTML 渲染
  • SQL 拼接发生在 sql:query 或 sql:update 执行前,此时 EL 表达式已求值完毕
  • 真正防注入必须靠参数化查询,即占位符 + 绑定值

用 sql:param 实现参数化查询的正确姿势

sql:param 是 JSTL SQL 库中唯一能将用户输入作为预编译参数传入的标签,它配合 ? 占位符使用,底层调用的是 PreparedStatement.setXXX()。

使用场景:仅适用于简单 CRUD,且数据库连接由 sql:setDataSource 配置;不适用于动态列名、表名或复杂条件拼接。

<setdatasource var="ds" driver="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/test" user="root" password="123"></setdatasource><query datasource="${ds}" var="rs">
    SELECT * FROM user WHERE status = ? AND age > ?
    <param value="${param.status}">
<param value="${param.age}"></query>
  • 每个 ? 必须对应一个 sql:param,顺序严格匹配
  • value 属性支持 EL,但不能是表达式链(如 ${param.x.y} 在部分旧版 JSTL 中可能失败,建议先存到 pageScope 变量)
  • 类型自动推断:字符串进 setString(),数字进 setInt();若需指定类型(如 java.time.LocalDate),JSTL 不支持,得换原生 JDBC

容易被忽略的兼容性与限制

JSTL SQL 标签库早在 Java EE 5 时代就被标记为“不推荐用于生产”,现在多数容器(Tomcat 10+、Jetty 12)默认不加载 javax.servlet:jstl,更不支持 sql:param。

cn-json-diff
cn-json-diff

比较两个 JSON 文件并显示差异。支持嵌套结构、数组及值变更。纯 Python 标准库实现,无需 API 密钥。

下载

错误信息示例:org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/sql cannot be resolved。

  • JSP 页面顶部必须声明:,且 classpath 下要有 jstl.jar 和 standard.jar(或 Jakarta 版本)
  • Jakarta EE 9+ 迁移后,URI 变为 https://jakarta.ee/xml/ns/jstl/sql,旧 sql:param 标签名不变但需新依赖
  • 无法处理 NULL 值:当 ${param.id} 为空时,sql:param 会传空字符串而非 SQL NULL,导致查询逻辑错误

真正该做的:别用 JSTL SQL 标签库

不是优化写法的问题,而是整个 sql:* 标签体系缺乏事务控制、连接池管理、异常分类,且无法复用 DAO 层逻辑。现代项目中,所有数据库操作应下沉到 Servlet、Filter 或 Spring Controller 中完成。

替代方案很简单:用 PreparedStatement 手写 JDBC,或引入 MyBatis、JPA 等框架——它们天然支持参数绑定,且 #{} 或 @Param 语法比 sql:param 更可靠、可测、可调试。

如果非要在 JSP 里快速原型,至少确保:① 所有用户输入只进 sql:param,绝不拼 SQL 字符串;② 数据源配置启用预编译(MySQL 加 useServerPrepStmts=true);③ 关闭 JSTL SQL 的 autoCommit(通过 sql:update 的 commit="false" 配合 sql:transaction)。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

js sql注入

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

3789

3

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

2023.07.25

2488

9

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

2023.08.02

1440

5

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.09

1358

4

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

2023.09.05

1456

5

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2418

7

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

2023.09.20

4040

8

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

2023.09.22

19315

6

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

569

3

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.9万人学习