SSM 框架的审计思路其实就是代码的执行思路。
与审计非 SSM 框架代码的主要区别在于 SSM 框架的各种 XML 配置,注解配置需要用户根据 XML 中的配置和注解来查看代码的执行路径、SSM 框架中常见的注解和注解中的属性,以及常见的标签和标签的各个属性。
审计漏洞的方式与正常的 Java 代码审计没有区别,网上有很多非常优秀的 Java代码审计文章,关于每个漏洞的审计方式写得都非常全面,我们需要做的只是将其移植到 SSM 框架的审计中来。明白 SSM 的执行流程后自然就明白怎样在 SSM 框架中跟踪参数,例如刚刚介绍的 XSS 漏洞。我们根据 XML 中的配置和注解中的配置找到了 MyBatis 的 mapper.xml 这个映射文件,以及最终执行的以下命令。
insert into ssmbuild.books(bookName,bookCounts,detail)
values (#{bookName}, #{bookCounts}, #{detail})
观察这个 SQL 语句,发现传入的 books 参数直到 SQL 语句执行的前一刻都没有经过任何过滤处理,所以此处插入数据库的参数自然是不可信的脏数据。再次查询这条数据并返回到前端时就非常可能造成存储型 XSS 攻击。
在审计这类漏洞时,最简单的方法是先在 web.xml 中查看有没有配置相关的过滤器,如果有则查看过滤器的规则是否严格,如果没有则很有可能存在漏洞。
最后补充一下 MyBaits 中的预编译知识。在非预编译的情况下,用户每次执行SQL 都需要将 SQL 和参数拼接在一起,然后传递给数据库编译执行,这种采用拼接的方式非常容易产生 SQL 注入漏洞,用户可以使用 filter 对参数进行过滤来避免产生SQL 注入。
而在预编译的情况下,程序会提前将 SQL 语句编译好,程序执行时只需要将传递进来的参数交由数据库进行操作即可。此时不论传递进来的参数是什么,都不会被当作 SQL 语句的一部分,因为真正的 SQL 语句已经提前被编译好了,所以即使不过滤也不会产生 SQL 注入这类漏洞,以下面 mapper.xml 中的 SQL 语句为例。
insert into ssmbuild.books(bookName,bookCounts,detail)
values (#{bookName}, #{bookCounts}, #{detail})