当前位置: 首页 > news >正文

从程序被SQL注入来MyBatis 再谈 #{} 与 ${} 的区别

缘由

最近在的一个项目上面,发现有人在给我搞 SQL 注入,我真的想说我那么点资源测试用的阿里云服务器,个人估计哈,估计能抗住他的请求。狗头.png

系统上面的截图
系统上面的截图

数据库截图
数据库截图

说句实在的,看到这个之后我立马就是在想啊,现在我们都是用的成熟的ORM 框架,一般调用 ORM 框架的方法操作数据库是不会有问题的。

后面又让我想起来了,#{}${} 的区别,这里总结下,说一句通俗易懂的话:使用 #{} 可以防止SQL注入,使用 ${} 就会出现 SQL 注入。

代码理解

咱们都是程序员,都喜欢说,别给我说那么多废话,show me the code,那么我们直接看代码把,我们通过伪代码来理解下:

 public void test(String name, String id){String sql = "update orders set name = "+name+" where id = ?";}

这里我为了方便与说明,就是使用上面的一个SQL 来解析,从上面的 SQL 可以看到两点信息:

  • name: 是直接使用了拼接字符串的方式,这里就是类似于 ${} 做的事情
  • id:使用了 ? 做为占位符,做了一次预处理,先去编译SQL,后面再来做参数化操作,这个是 #{} 的具体原理

如果是 name 被恶意传入了 SQL 代码,比如:

") OR (SELECT*FROM(SELECT(SLEEP(3)))hnao) limit 1#
-- 或者
" union select 1-- 

那么解析出来的 SQL 就会变成:


update orders set name = ) OR (SELECT*FROM(SELECT(SLEEP(3)))hnao) limit 1update orders set name = union select 1

虽然上面比较难看,因为我这里举例是 update,如果是查询呢:

select name from orders  union select 1-- 

那这样子是不是就出问题了?其实只要他成功一次,那么就可能窃取到我们数据库的信息了。

#{}${} 的区别

这里我也去百度了下,然后整理一下大致的区别,在 MyBatis 中,#{}${} 都是用于在 SQL 语句中插入参数的占位符,但它们之间有着显著的区别。

  1. 预编译与安全性

    • #{}:这是一个预编译(PreparedStatement)的占位符。当 MyBatis 在解析 XML 映射文件或注解中的 SQL 时,它会为 #{} 中的参数生成一个 PreparedStatement,并使用 ? 作为占位符。这意味着 SQL 语句会被预编译,并且在执行时会使用参数化查询,这样可以防止 SQL 注入攻击。
    • ${}:这是一个简单的字符串替换。MyBatis 会直接替换 ${} 中的内容为 SQL 语句中的相应部分。这意味着 SQL 语句不会被预编译,而是会动态地构建和执行。这可能会导致 SQL 注入攻击,因为它允许不受限制的字符串替换。
  2. 用法

    • #{}:通常用于插入参数值,例如列值、条件值等。
    • ${}:通常用于插入 SQL 片段,如表名、列名、动态 SQL 语句等。
  3. 动态 SQL

    • 在 MyBatis 中,${} 更多地用于构建动态 SQL,因为它允许直接替换 SQL 语句中的任何部分。然而,由于这种灵活性,它也增加了 SQL 注入的风险。
    • #{} 在动态 SQL 中通常用于插入参数值,以确保安全性。
  4. 类型处理器

    • 对于 #{} 插入的参数,MyBatis 会使用相应的类型处理器(Type Handler)来确保参数与数据库中的列类型匹配,并进行必要的类型转换。
    • 而对于 ${},由于它直接替换 SQL 语句中的部分,因此不会使用类型处理器。
  5. 注意事项

    • 尽可能使用 #{} 来插入参数值,以确保 SQL 语句的安全性和性能。
    • 如果确实需要使用 ${}(例如,插入表名或列名),请确保传入的字符串是安全的,并且不包含任何来自不受信任的来源的内容。
    • 在使用动态 SQL 时,要特别注意 SQL 注入的风险,并采取相应的预防措施。

总之,#{}${} 在 MyBatis 中各有其用途,但 #{} 通常更安全、更可靠,并应优先使用。

相关文章:

  • Python pdf2imges -- pdf文件转图片
  • QT:信号与槽
  • WordPress安装memcached提升网站速度
  • Value-Based Reinforcement Learning(2)
  • 2024.5.26.python.exercise
  • pod 之资源限制 与健康检查
  • Vue项目中npm run build 卡住不执行的几种情况(实战版)
  • P2118 [NOIP2014 普及组] 比例简化
  • Spring从零开始学使用系列(四)之@PostConstruct和@PreDestroy注解的使用
  • 化学中的不确定性。
  • 人工智能+量子计算:飞跃现实边界还是科技幻想?
  • java网络:过滤器修改请求头
  • 一、Elasticsearch介绍与部署
  • 【知识拓展】LocalTunnel-高性价比的内网穿透工具(2)
  • matplotlib latex表格
  • [ JavaScript ] 数据结构与算法 —— 链表
  • __proto__ 和 prototype的关系
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • 【React系列】如何构建React应用程序
  • ECS应用管理最佳实践
  • gf框架之分页模块(五) - 自定义分页
  • JAVA_NIO系列——Channel和Buffer详解
  • JavaScript设计模式与开发实践系列之策略模式
  • Linux链接文件
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 基于 Babel 的 npm 包最小化设置
  • 驱动程序原理
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​数据链路层——流量控制可靠传输机制 ​
  • ​香农与信息论三大定律
  • # Redis 入门到精通(九)-- 主从复制(1)
  • $(selector).each()和$.each()的区别
  • $forceUpdate()函数
  • (1)Hilt的基本概念和使用
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (独孤九剑)--文件系统
  • (二)hibernate配置管理
  • (二)WCF的Binding模型
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)计算机毕业设计大学生兼职系统
  • (含答案)C++笔试题你可以答对多少?
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (六)DockerCompose安装与配置
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (十八)SpringBoot之发送QQ邮件
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • (自适应手机端)行业协会机构网站模板
  • .a文件和.so文件