sql注入把系统搞崩溃,该怎么解决(三)

开课吧开课吧锤锤2021-05-08 10:12

点赞
有用
分享分享

    Java编程语言是一种简单、面向对象、分布式、解释型、健壮安全、与系统无关、可移植、高性能、多线程和动态的语言。如今Java已经广泛应用于各个领域的编程开发。

java

    5.有些特殊的场景怎么办?

    在java中如果使用mybatis作为持久化框架,在mapper.xml文件中,如果入参使用#传值,会使用预编译机制。

    一般我们是这样用的:

<sql id="query">
   select * from user 
   <where>
     name = #{name}
   </where>
</sql>

    绝大多数情况下,鼓励大家使用#这种方式传参,更安全,效率更高。

    但是有时有些特殊情况,比如:

<sql id="orderBy">
   order by ${sortString}
</sql>

    sortString字段的内容是一个方法中动态计算出来的,这种情况是没法用#,代替$的,这样程序会报错。

    使用$的情况就有sql注入的风险。

    那么这种情况该怎办呢?

    自己写个util工具过滤掉所有的注入关键字,动态计算时调用该工具。

    如果数据源用的阿里的druid的话,可以开启filter中的wall(防火墙),它包含了防止sql注入的功能。但是有个问题,就是它默认不允许多语句同时操作,对批量更新操作也会拦截,这就需要我们自定义filter了。

    6.表信息是如何泄露的?

    有些细心的同学,可能会提出一个问题:在上面锁表的例子中,攻击者是如何拿到表信息的?

    方法1:盲猜

    就是攻击者根据常识猜测可能存在的表名称。

    假设我们有这样的查询条件:

select * from t_order where id = ${id};

    传入参数:-1;select*fromuser

    最终执行sql变成:

select * from t_order where id = -1;select * from user;

    如果该sql有数据返回,说明user表存在,被猜中了。

    建议表名不要起得过于简单,可以带上适当的前缀,比如:t_user。这样可以增加盲猜的难度。

    方法2:通过系统表

    其实mysql有些系统表,可以查到我们自定义的数据库和表的信息。

    假设我们还是以这条sql为例:

select code,name from t_order where id = ${id};

    第一步,获取数据库和账号名。

    传参为:-1unionselectdatabase(),user()#

    最终执行sql变成:

select code,name from t_order where id = -1 union select database(),user()#

    会返回当前数据库名称:sue和账号名称:root@localhost。

java

    第二步,获取表名。

    传参改成:-1unionselecttable_name,table_schemafrominformation_schema.tableswheretable_schema='sue'#

    最终执行sql变成:

select code,name from t_order where id = -1 union select table_name,table_schema from information_schema.tables where table_schema='sue'#

    会返回数据库sue下面所有表名。

JAVA

    以上就是开课吧开课吧老师苏三说技术的“sql注入把系统搞崩溃,该怎么解决(三)”一文,更多Java教程相关内容尽在开课吧广场Java教程频道!

有用
分享