以java-sec-code为例子,对CodeQL提供的官方规则进行修改优化,更契合项目本身的规则。
\ql\src\experimental\Security\CWE\CWE-089
\MyBatisMapperXmlSqlInjection.ql
有个是关于MyBatisMapper注入规则,现在我们看下效果如何
可以看到,一共找到了9个注入点,那我们去看看这9个是不是都是注入点,人工验证一下。
在CodeQL的插件这里,右键点击我们导入的数据库,将源码添加到我们的工作区
接下来就会在工作区发现我们的java项目
原本是在左下角,有点小,看得很麻烦,可以直接拖到控制台,放大看我们可以看到,刚刚好有9个,那就是CodeQL官方规则扫描发现这9个都存在注入,实际上并不是全部存在注入,明显存在误报,所以接下来我们要对官方的规则进行优化。
分析一下MyBatisMapperXmlSqlInjectionLib
,在
\ql\java\ql\src\experimental\Security\CWE\CWE-089
\MyBatisMapperXmlSqlInjectionLib.qll
这里,点击Quick Evaluation进行查询
MyBatisMapperMethodCallAnArgument
构造函数使用了exists
关键字,其作用是在CodeQL查询中定义存在某种关联关系或满足某种条件的情况,从而影响查询结果。exists
中,定义了两个变量 MyBatisMapperSqlOperation mbmxe
和 MethodCall ma
,它们分别表示 MyBatis 映射器的 SQL 操作和方法调用。mbmxe.getMapperMethod() = ma.getMethod()
指定了 mbmxe
的映射方法与 ma
的调用方法相匹配。ma.getAnArgument() = this.asExpr()
指定了方法调用m*
的一个参数与当前实例相匹配。MyBatis Mapper
的sinkisSanitizer
方法,isSanitizer是CodeQL的类TaintTracking::Configuration提供的净化方法。CodeQL从入门到放弃 - FreeBuf网络安全行业门户
https://www.freebuf.com/articles/web/283795.html
override predicate isSanitizer(DataFlow::Node sink){
exists(Call call |
sink.asExpr() = call.getArgument(0) and
//这里是检查方法调用的调用者是否是名为sqlFilter的
call.getCallee().toString() = "sqlFilterd"
) or
sink.getType() instanceof PrimitiveType or
sink.getType() instanceof BoxedType or
sink.getType() instanceof NumberType or
exists(ParameterizedType pt| sink.getType() = pt and pt.getTypeArgument(0) instanceof NumberType )
}
predicate querySink(DataFlow::Node sink) {
exists(Method method, MethodAccess call |
method.hasName("executeQuery")
and call.getMethod() = method
and sink.asExpr() = call.getArgument(0)
)
}
import MyBatisMapperXmlSqlInjectionLib
MyBatisMapperXmlSqlInjectionLib.qll
同级目录import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import MyBatisMapperXmlSqlInjectionLib
class SqlinjectConfiguration extends TaintTracking::Configuration{
SqlinjectConfiguration() {
this = "java-sec-code SqlinjectConfiguration"
}
override predicate isSource(DataFlow::Node source){
source instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node sink) { sink instanceof MyBatisMapperMethodCallAnArgument or querySink(sink)}
override predicate isSanitizer(DataFlow::Node sink){
exists(Call call |
sink.asExpr() = call.getArgument(0) and
call.getCallee().toString() = "sqlFilter"
) or
sink.getType() instanceof PrimitiveType or
sink.getType() instanceof BoxedType or
sink.getType() instanceof NumberType or
exists(ParameterizedType pt| sink.getType() = pt and pt.getTypeArgument(0) instanceof NumberType )
}
predicate querySink(DataFlow::Node sink) {
exists(Method method, MethodAccess call |
method.hasName("executeQuery")
and call.getMethod() = method
and sink.asExpr() = call.getArgument(0)
)
}
}
from SqlinjectConfiguration dataflow, DataFlow::Node source, DataFlow::Node sink
where dataflow.hasFlow(source, sink)
select "source", source, "sink", sink, , source.getLocation()
https://www.freebuf.com/articles/web/283795.html
https://www.ctfiot.com/65681.html
https://github.com/SummerSec/learning-codeql
https://codeql.github.com/docs
https://www.yuque.com/loulan-b47wt/rc30f7/pchp0a
END
如您有任何投稿、问题、需求、建议
请NOVASEC公众号后台留言!
或添加 NOVASEC 联系人
感谢您对我们的支持、点赞和关注
加入我们与萌新一起成长吧!
本团队任何技术及文件仅用于学习分享,请勿用于任何违法活动,感谢大家的支持!!