Record

2023-08-06

predicate 没有返回值,做限定

exists 根据内部的子查询返回true or false

1
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }

这是SDK自带的规则,里面包含了大多常用的Source入口。我们使用的SpringBoot也包含在其中


1、找一个新版的简单点,能跑的 dos 脚本,有的话最好,然后根据老版的dos思路改

2、直接把老版的思路改,显然有点不符合实用主义

https://github.com/webraybtl/CodeQLpy

CWE-730 redos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* 表达式声明:
* Expr expSrc,
*
* 方法声明:
* Method method
* Method:Method是一个表示Java程序中方法的类。它包含有关方法的信息,如方法名称、所在的类、
* 参数类型、返回类型等。你可以使用Method来分析方法的定义、签名和其他属性。
*
* 方法的访问,所有方法的属性:
* MethodAccess:MethodAccess是一个表示Java程序中对方法的访问的类。它包含有关方法访问的信息,
* 如方法调用的位置、参数传递、调用者等。你可以使用MethodAccess来分析方法的调用、使用情况和调用者的上下文。
*
* 简而言之,Method用于表示方法的定义和属性,而MethodAccess用于表示方法的访问和调用。
*
* 在CodeQL查询中,你可以使用这两个类来进行不同类型的分析。例如,你可以使用Method来查找具有特定属性的方法,
* 如静态方法、私有方法或抽象方法。而使用MethodAccess则可以查找调用了特定方法的代码行,或者分析方法的调用图。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* 该脚本用于测试DoS漏洞,检查传递的参数是否进行了适当的限制。
* 请将待测试的Java源代码与该脚本放在同一个CodeQL项目中进行分析。
*/

import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking

// Rule: 检查数据库查询的参数是否有限制一次性的查询数量
predicate hasUnrestrictedQuery(db: Database, query: Expr) : bool {
exists(MethodAccess methodAccess |
methodAccess.getMethod().getName() = "executeQuery" and
methodAccess.getArgument(0) = query and
methodAccess.getQualifier() = db
)
}

// Rule: 检查传递的pagesize参数是否进行了适当的限制
predicate hasUnrestrictedPageSize(pageSize: Expr) : bool {
exists(MethodAccess methodAccess |
methodAccess.getMethod().getName() = "setPageSize" and
methodAccess.getArgument(0) = pageSize
)
}

// Rule: 检查类中具体参数是否进行了适当的限制
predicate hasUnrestrictedParameter(classType: Type, parameter: Parameter) : bool {
exists(MethodAccess methodAccess |
methodAccess.getMethod().getDeclaringType() = classType and
methodAccess.getArgument(parameter.getIndex()) = parameter
)
}

// Rule: 检查List的长度是否进行了适当的限制
predicate hasUnrestrictedListSize(list: Expr) : bool {
exists(MethodAccess methodAccess |
methodAccess.getMethod().getName() = "size" and
methodAccess.getQualifier() = list
)
}

// Rule: 检查DoS漏洞
from MethodAccess methodAccess, Method method, Parameter parameter, ClassType classType, Expr pageSize, Expr list
where
methodAccess.getMethod() = method and
methodAccess.getArgument(parameter.getIndex()) = pageSize and
methodAccess.getMethod().getDeclaringType() = classType and
methodAccess.getQualifier() = classType and
hasUnrestrictedQuery(_, pageSize) or
hasUnrestrictedPageSize(pageSize) or
hasUnrestrictedParameter(classType, parameter) or
hasUnrestrictedListSize(list)
select methodAccess, "Potential DoS vulnerability: unrestricted parameter usage"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* @name Arbitrary file write during archive extraction ("Zip Slip")
* @description Extracting files from a malicious archive without validating that the
* destination file path is within the destination directory can cause files outside
* the destination directory to be overwritten.
* @kind path-problem
* @id java/zipslip
* @problem.severity error
* @security-severity 7.5
* @precision high
* @tags security
* external/cwe/cwe-022
* Zip Slip是一个广泛存在的关键存档提取(critical archive extraction)漏洞,
* 该漏洞允许攻击者在系统中任意写文件,尤其是会导致远程命令执行。
*
* zip解压,任意文件上传
* source应该是识别外面输入的压缩文件
* sink应该是解压操作
*/

import java
import semmle.code.java.security.ZipSlipQuery
import ZipSlipFlow::PathGraph
//导入PathGraph命名空间,并将其视为ZipSlipFlow命名空间的子命名空间。
//因此,PathGraph命名空间中定义的查询文件或模块可以在ZipSlipFlow命名空间中使用。

// ZipSlipFlow 也是调用的 DataFlow::Node,识别sink为 archive entry
// A sink that represents a file creation, such as a file write, copy or move operation.
from ZipSlipFlow::PathNode source, ZipSlipFlow::PathNode sink
where ZipSlipFlow::flowPath(source, sink)
select source.getNode(), source, sink,
"Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(),
"file system operation"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
source: 获取到入参为类参数且其中包含 List<> / BatchVO<> 字段

sink:
1、(1.1)类中是否有长度限制注解,(1.2)是否有自定义写的size判断,foreach循环
2、(1)是否 List 字段赋值给其他变量,(2)新的 List 变量是否有做限制,foreach循环

0、获取所有参数为类,类名不包括<,类成员包括 List<>
1、判断方法是否有类注解 @PaginationCheck
2、判断类参数涉及 List是否有 @Size 注解
3、判断类参数是否调用 size()方法做判断


处理措施:
1、类注解 @PaginationCheck
2、类成员变量注解 @Size
3、List<>可以在参数声明限制,参数声明注解 @Size
4、手段判断 if (xx.size() > xx ) 限制

为什么参数名为 p0
*/
import java

// 定义一个规则来判断参数是否为List类型
// predicate isListParameter(Parameter p) {
// p.getType().implementsInterface("java.util.List")
// }

// from Class c, Parameter p
// where p.getType().(Class) = c
// // and not exists(c.getName().indexOf("<"))
// and c.getName() = "MultipartFile"
// // c.getAField().getType()
// select c.getName(), c.getAField(), c.getAField().getType(), p.getName()

// 判断方法中是否包含类参数
// predicate isListParameter(MethodAccess m) {
// exists(Class c | m.getParameter)
// }

// 创建一个谓词来遍历方法的每个参数名和值
// predicate traverseMethodArguments(MethodAccess methodAccess, string methodName, Expr[] arguments, string argumentName, Expr argumentValue) {
// // 确定方法调用的名称和参数
// methodAccess.getMethod().getName() = methodName and
// methodAccess.getArguments() = arguments and
// // 使用谓词来遍历参数名和值
// methodAccess.getArgumentName(argumentName, argumentValue)
// }

predicate hasSize(Class c){
exists(Annotation a, Parameter p | p.getType().(Class) = c
and not exists(c.getName().indexOf("<"))
and exists(c.getAField().toString().indexOf("List<"))
and a.getAnnotatedElement() = c.getAField()
and a.toString() = "Size"
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
根据你的最新信息,如果 implementsInterface 被弃用了,那么在最新版本的 CodeQL 中判断类型的方法可能会有所不同。在这种情况下,你可以使用 instanceOf 谓词来判断类型是否符合你的需求。以下是一个示例代码,演示了如何使用 instanceOf 谓词来判断类型是否为 List<>:

import java

// 查询入口:查找类型为 List<> 的成员
from ClassMember member
where
// 判断成员的类型是否为 List<>
member.getType() instanceof ClassType and
member.getType().asClassType().getQualifiedName() = "java.util.List"
select member
在上述查询代码中,我们使用 instanceof 谓词来检查成员的类型是否为 ClassType,然后使用 asClassType() 方法获取类类型,最后判断类类型的限定名称是否为 "java.util.List"。

请根据你的具体需求修改查询条件和类名称,以适应你的情况。

如果你还有其他问题或需要进一步帮助,请随时提问。