经销商技术部-防SQL注入实践

网络安全现在越来越受到重视,其中后端应用最常见的安全漏洞就是SQL注入,据owasp(开放式Web应用程序安全项目组织)的安全漏洞统计,注入漏洞常年排名TOP 3。为了尽可能地减少SQL注入问题,我们进行了一些实践总结,并在部门内部进行了推广。

SQL注入原理

SQL注入攻击是通过操作输入来修改SQL语句,以达到执行注入的SQL、进而对web服务器进行攻击的方法。简单的说就是在web表单或页面请求的查询字符串中插入SQL命令, 最终使web服务器执行恶意命令的过程。可以通过一个例子简单说明SQL注入攻击。假设某网站页面显示时URL为http://www.example.com?test=123,此时URL实际向服务器传递了值为123的变量test,这表明当前页面是对数据库进行动态查询的结果。如果服务器使用了SQL动态拼接,此时可以在URL中插入恶意SQL语句并执行。例如预期执行语句是:

select * from user where testId = 123

如果有人恶意构造test=123 or 1 = 1;那么最后实际执行的语句就是:

select * from user where testId = 123 or 1 = 1

SQL注入本质是利用动态SQL拼接并直接执行,并且前端输入的参数未经过严格校验直接参与SQL拼接,输入参数被恶意利用的话就存在不受控的命令注入风险。SQL注入会攻击数据库,所以危害是非常大的,SQL注入的危害包括:1. 数据库信息泄露;2. 数据库恶意操作攻击服务器;3. 删除和修改数据库表信息;4. 服务器远程控制等。防SQL注入原则根据SQL注入的原理,我们总结了如下防SQL注入的原则。1)尽可能参数化执行SQL,使用PreparedStatement;2)无法参数化执行就对输入参数使用强类型接收,如枚举;3)如果既不能参数化也无法用强类型,就做好格式校验;4)如果上面都做不到,最后考虑做好注入字符的转义过滤。

防SQL注入实践总结

  • 实践1:使用数据库预编译SQL执行

关系型数据库都提供了预编译执行SQL语句的方式,和直接执行有参数拼接的SQL方式不同的是,在SQL预编译阶段,所有参数都会被模板化,参数值不直接参与编译,这样参数值就无法改变SQL的结构,包括语句条数,参数个数,查询条件等等,就算参数里存在恶意注入参数值也无法破坏原来的SQL结构。下面举例说明拼接执行和参数化执行的区别。直接执行:

select name from user_info where name = 'gouge'

使用预编译执行(也就是PreparedStatement)分两步。

第一步:模板化编译

select name from user_info where name = ?

第二步:参数带入

select name from user_info where name = 'gouge'

预编译后的语句执行时,就算参数值里有恶意注入,也只是当成一个字符串的一部分,并不会导致SQL结构被破坏,所以这种方式能够从根本上杜绝SQL注入的风险,也是目前公认防SQL注入最好的办法。

  • 实践2: 可选情况下,优先使用非String类型作为入参

SQL注入依赖于SQL动态拼接,如果非String(包括枚举)参数有强类型严格校验,拼接的时候就没有SQL注入的风险

  • 实践3:对String类型参数进行枚举校验

对于可枚举的String入参,在后端需要进行枚举值白名单校验,防止伪造。以经常使用的排序字段为例,排序字段不少情况下是从前端传过来的,不可信。所以需要做枚举校验,看看传过来的排序字段是否在预期内。

  • 实践4:存储过程

存储过程因为也是预编译的,所以也可以防止SQL注入,不过存储过程已经是不推荐的实践了,这里只是列举一下。

  • 实践5:对String入参进行转义处理

这个实践方案的优先级最低,前面的方案都无法实施或代价太大的情况下,才考虑使用,因为这个办法并不是完全可靠的。这个办法是把用户输入拼到SQL之前,先对输入进行转义,所以实现上是和数据库绑定的,不同的数据库转义实现都不一样。原理是对特定的查询,数据库支持一种或多种转义的方法,如果对所有用户输入的参数拼到SQL之前进行合适的转义,就可以防止SQL注入,但是不能保证所有情况都能处理完美。OWASP组织提供了可以直接使用的java类库esapi,可以用来完成转义,目前支持mysql,oracle,还不支持sqlserver,OWASP官方文档中也有说明这个类库也不能保证100%可以防SQL注入。

Mybatis防SQL注入

Mybatis的XML Mapper中参数有两种表达方式: #{xxx}和${xxx},区别是#{xxx}会被模板化为参数化形式(?),所以参数值不参与编译;${xxx}会被替换为对应的参数值参与编译。所以使用#{xxx}语法的参数没有注入风险,但是使用${xxx}不当,就存在注入风险。我们使用sonar规则来检测${xxx}的使用情况,发现很多可以使用#{xxx}的情况下,却使用了${xxx},大概是使用者还不了解其中的区别和风险。根据防止SQL注入的原则,针对使用Mybatis作为ORM的时候,我们可以得出这样的结论:

  • 在xml中能使用参数化#{}语法实现的,禁止使用${}
  • 不得已必须使用${}语法拼接SQL时,必须先进行合法校验和转义

Mybatis-XML常见误用及安全建议

1)常规误用风险写法:

account = '${account}'

安全写法:

account = #{account}

2) in 参数拼接风险写法:

WHERE id IN (${item.ids})

安全写法:

<if test="ids != null and ids.size() > 0">
AND id IN
<foreach
collection="ids"
item="id"
open="("
separator=","
close=")">
#{id}
</foreach>
</if>

3) sqlserver top语法风险写法:

top ${queryCnt}

安全写法:

top (#{queryCnt})

4)between语法风险写法:

BETWEEN ${start}AND ${end}

安全写法:

BETWEEN #{start}AND #{end}

5)like语法风险写法:

email like'%${emailSuffix}'

安全写法1:

email like concat('%', #{emailSuffix})

安全写法2:

<bind name="pattern" value="'%'+ emailSuffix">
Email like #{pattern}

安全写法3:在java代码中构造好pattern,使用#{}语法6) limit语法风险写法:

limit ${offset}, ${size}

安全写法:

limit #{offset}, #{size}

7) 动态order by风险写法:

orderby ${orderByClause}

安全建议1:可以在xml中使用if代替java中拼凑orderby(推荐);安全建议2:对排序字段和排序类型值进行白名单校验;8)动态表名安全建议:建议实现Mybatis插件,在框架层面对表名进行替换处理,避免在xml使用${}来拼凑表名。9) Mybatis example语法风险用法:

<if test="orderByClause != null">
orderby ${orderByClause}
</if>

Mybatis生成的example使用,大多数情况下是安全的,但是orderByCluase是通过字符串拼接的,也是不安全的,所以不建议使用。安全建议:可以考虑使用mybatis新出的mybatis-dynamic-sql或者国内开源的mybatis-plus,比example语法更简洁,也更安全。例如:

Query.orderBy(createAt.descending());

WAF除了在SQL语句层面尽量保证防止SQL注入风险之外,基础设施WAF(Web Application Firewall)也是非常有效的防止SQL注入的措施,有条件的也可以考虑部署WAF。

总结

本文主要是记录了经销商技术部在安全方面防止SQL注入的一些实践探索和总结,包括SQL注入的原理,防SQL注入总体遵循的原则,以及具体的实践中的安全建议,希望对其他人也有所帮助。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/149686.html<

(0)
管理的头像管理
上一篇2025-03-12 17:47
下一篇 2025-03-12 17:48

相关推荐

  • 骨干网络体系结构能干什么?骨干网络体系结构的作用

    骨干网络体系结构是现代信息社会的“超级高速公路网”,它通过分层设计、冗余备份和智能调度,确保海量数据在全球范围内高速、稳定、安全地传输,是支撑云计算、物联网及人工智能应用的底层基石,想象一下,如果你把互联网比作一个巨大的城市交通系统,那么骨干网络就是连接各个城市的主干道和立交桥,没有它,你的每一次微信发送、每一……

    2026-06-18
    0
  • 高io数据库可以干什么用?高io数据库适合什么场景

    高IO数据库的核心价值在于通过极高的读写吞吐量,解决海量数据场景下的性能瓶颈,是支撑高并发交易、实时分析及大规模内容分发的关键基础设施,在数字化转型的深水区,数据不再仅仅是静态的记录,而是流动的资产,传统的机械硬盘或普通SSD早已无法满足现代应用对速度的极致追求,高IO(Input/Output)数据库,就是那……

    2026-06-18
    0
  • 高io服务器性能如何?高io服务器适合什么场景

    高IO服务器并非单纯指代某种硬件,而是指在随机读写、高并发连接及小文件处理场景下,具备极致IOPS(每秒输入输出操作次数)和低延迟特性的计算资源,它是支撑现代高并发应用稳定运行的核心基石,在2026年的数字化浪潮中,业务负载早已从简单的静态页面展示演变为复杂的实时数据处理,许多开发者在排查系统瓶颈时,往往忽略了……

    2026-06-18
    0
  • 隔离网络空间哪里便宜?国内隔离网络空间价格

    隔离网络空间并没有统一的“便宜”标准,其成本高度取决于物理隔离等级、带宽需求及安全合规要求,通常物理网闸方案初期投入较高但长期运维成本低,而逻辑隔离方案虽初期便宜但存在潜在安全风险,建议根据业务敏感度选择混合隔离架构以平衡成本与安全,在数字化时代,企业构建独立网络环境的需求日益增长,但“隔离网络空间哪里便宜”这……

    2026-06-18
    0
  • 骨干网络体系结构设备为何故障?常见原因有哪些

    骨干网络体系结构设备故障的核心原因通常归结为硬件老化、配置错误、物理链路中断及外部攻击四大类,其中电源模块失效与光模块性能衰减是占比最高的隐性故障源,骨干网作为数字经济的“大动脉”,其稳定性直接关乎国计民生,当核心路由器或交换机出现丢包、震荡甚至宕机时,运维人员往往面临巨大的压力,很多人第一反应是检查软件配置……

    2026-06-18
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注