当前位置: 首页 > 科技观察

什么是SQL注入,这些坑都得绕开

时间:2023-03-17 19:53:36 科技观察

1.什么是sql注入?sql注入是用户输入的参数,拼接到原来的sql中,成为sql的一部分,从而影响sql的功能和执行结果2.sql注入破坏力-小兵破坏力。比如原来的sql是这样的:select*fromuserwherename='username'andpassword='password';用户输入名称:甄大虾'--'注意密码:password然后猜猜最后的结果是什么?select*fromuserwherename='甄大虾'--'评论'andpassword='密码';二--代表注释,所以这个sql只需要输入用户名就可以获取用户信息,跳过密码的验证-boss破坏力很大,比如用户输入如下参数名:虎大虾密码:';droptableuser;--'注释最后的sql:select*fromuserwherename='百大虾'andpassword='';droptableuser;--'Comment';用户表实际上被删除了。看到这里,你这时候可能就想原地爆炸了。三、对策3.1.PreparedStatement预编译使用预编译,这样传入的参数会被当作字符串处理,也就是用引号包起来。就拿刚才的例子,用户输入name:zhenprawn'--'注意密码:如果密码是预编译的,那么最后的sqlselect*fromuserwherename='zhenprawn\'--\'comment'andpassword='password';参数中的引号进行了转义,以免成为sql的一部分。3.2.某些语句无法预编译。预编译根据#获取参数,$表示拼接。#{}:解析为预编译语句的参数占位符${}:只作为字符串,在动态sql中直接替换变量,传入什么值就是值。比如传入:'甄大虾'or1=11,SELECT*FROMuserWHEREname=#{name}//SELECT*FROMuserWHEREname='\'甄大虾'or1=1'2,SELECT*FROMuserWHEREname=${name}//SELECT*FROMuserWHEREname='甄虾'or1=1但是在某些情况下,使用#会报错,比如像,in中如果使用#,就会报错,并且有一个orderby,sortedaccording对于传入的参数,这些情况下存在sql注入的危险,怎么办?likeselect*fromuserwherenamelike'%#{name}%'//会报错select*fromuserwherenamelike'%${name}%'//正常正确的写法使用mysql的字符串拼接函数concatselect*fromuserwherenamelikeconcat('%',#{name},'%')正确的写法,使用foreach@Select("")ListgetByIds(@Param("userIds")List<长>userIds);orderby有时候需要根据前端传入的参数进行排序。这时候就有sql注入的危险。这时候可以使用白名单比如List;allowSortColumnList=Lists.newArrayList("age","score");if(!allowSortColumnList.contains(sortParam)){thrownewRuntimeException("cannotsortby"+sortParam);}