您当前的位置: 首页 >  sql

石头wang

暂无认证

  • 0浏览

    0关注

    295博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

关于SQL注入(有例子)以及我的一些想法

石头wang 发布时间:2021-07-02 18:04:37 ,浏览量:0

背景

本文详细讨论sql注入的那些事情。聊聊自己的看法。并且会提供sql注入的例子。

sql注入的例子

例子就不用jdbc的 API 来演示了。我直接用了springboot+mybatis来模拟出来

1、代码
  • 写一个controller的接口

    @GetMapping("/user/list")
        public Object listUser(
                @RequestParam String name
        ) {
            return userService.listUser(name);
        }
    
  • service层的代码

    @Override
        public List listUser(String name) {
            return userMapper.listUser(name);
     }
    
  • dao层(这是最关键的)

    @Select({"",
                "select * from user where name='${name}'",
                ""})
        List listUser(@Param("name") String name);
    

    可以看到使用了 ${xxx} 而不是 #{xxx}

2、测试和总结

上述web跑起来后,参数传入

  • 正常访问:http://localhost:8888/user/list?name=stone

  • sql注入:http://localhost:8888/user/list?name=stone' or '1'='1

    这种方式,最终构造出来的sql是 select * from user where name='stone' or '1'='1',利用了or以及1=1恒成立。

3、进一步补充

除了上述,其实还可以利用注释符号,比如有些用 # 作为注释,有些用 --,mysql可以使用 #。如下:

select * from user_login where name='${name}' and password='${password}'

name传入 ' or 1=1; # ,password随便传什么值,最终会变成

select * from user_login where name='' or 1=1; #' and password='随便传什么值'

# 之后是注释,会被忽略。另外甚至可以传入 or 1=1;drop database test ;# 之类的,或者 or 1=1;delete from xxx ;# ,不过后面2个mybatis会报错,我没试验成功,总之你认为sql注入非常危险就是了。

解决方法
  • 如果你使用mybatis,使用 #{xxx} 替代 ${xxx} 就好了
  • 如果你用jdbc,使用PreparareStatement即可,即避免使用Statement,并且避免sql语句字符串拼接参数

PS:貌似mybatis-plus框架还搞了一些拦截器,拦截有问题的入参,有必要搞得这么复杂吗?不是使用 #{xxx} 就能解决吗? 难道就算使用 #{xxx} 也还是存在sql注入风险??

总结

其实感觉sql注入也没那么可怕。 首先,如果是内部使用的系统或者toB的话,人员没那么杂。 其次,就算是C端用户,也要猜到哪些操作对应后台的sql是可以进行注入的,就算知道了这条sql语句有问题,也很难知道sql的全貌,构造有问题的入参的时候很可能会导致sql根本就不能执行,即大概率sql执行是出错的。 最后,只要后端人员稍微规范一点用 #{xxx} 就可避免了。

关注
打赏
1663722529
查看更多评论
立即登录/注册

微信扫码登录

0.0414s