
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
1.数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
2.数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
3.服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
4.破坏硬盘数据,瘫痪全系统。
如代码采用如下写法
``select * from users where name = '" + userName + "'";
当 userName 被恶意传入:
- zz' or '1'='1
- 'or 1=1 --
- zz';drop table users;
将发生SQL注入,注入后果大家自己体会下。
"select * from users where employee_id = " + userID;
当userID被恶意传入
123 or 1=1
将发生SQL注入。
“别和我讲原理,别和我说漏洞,告诉我代码要怎么写就行” ——资深程序员
说完废话,我们以 JAVA MyBatis框架为例 说下各种场景下代码怎么写可以避免SQL注入漏洞。场景已覆盖全面,如果按下面的格式写代码可避免99%的SQL注入问题。
MyBatis在进行参数操作时支持#{参数}和${参数}两种形式,其中#{参数}为预编译方式,${参数}为拼接方式。
1. 通常情况下SQL语句都应使用预编译操作,禁止拼接SQL语句。
2. 特殊情况下(一般指order by、group by、表名)需要进行SQL拼接时,需在Services层对变量进行预定义转换,禁止将变量直接拼入SQL语句。
- 构建普通条件语句
- 构建like条件语句
- 构建in条件语句
- 构建order by语句
结果对比
结果对比
结果对比
order by 语句比较特殊 直接使用 #{} 会与程序员预期结果有出入。
对这种场景的处理 在Services层对变量进行预定义转换。
如
//先定义order by可能的字段
map.put("k1","epoch")
map.put("k2","date")
//获取用户提交的排序数据
String sortField = request.getParameter("sort");
// 判断用户提交数据是否在之前预定义的map里面
boolean result = fieldMap.containsKey(req_sortField);
if(result){
sortField = fieldMap.get(req_sortField).toString(); }
// Mybatis 配置文件
<select id="sortSQL">
SELECT * FROM Users
<if test="sortField" != null >
ORDER BY ${sortField}
</if>
</select>
普通条件语句 使用#{}
like 条件语句 使用#{}+CONCAT
in 条件语句 使用 #{} +foreach
order by条件语句 使用 ${} + 在Services层对变量进行预定义转换。
按以上示例写代码可屏蔽99%的SQL注入问题。
本文来源于:JAVA程序员如何彻底解决SQL注入漏洞-变化吧
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
-
- 加入Q群
- QQ扫一扫
-
评论