Repository navigation
Expand file tree
/
Copy pathSnakeYaml.qll
More file actions
89 lines (72 loc) · 2.65 KB
/
Copy pathSnakeYaml.qll
File metadata and controls
89 lines (72 loc) · 2.65 KB
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
* Provides classes and predicates for working with the SnakeYaml serialization framework.
*/
overlay[local?]
module;
import java
import semmle.code.java.dataflow.DataFlow
/**
* The class `org.yaml.snakeyaml.constructor.SafeConstructor`.
*/
class SnakeYamlSafeConstructor extends RefType {
SnakeYamlSafeConstructor() {
this.hasQualifiedName("org.yaml.snakeyaml.constructor", "SafeConstructor")
}
}
/**
* An instance of `SafeConstructor`.
*/
class SafeSnakeYamlConstruction extends ClassInstanceExpr {
SafeSnakeYamlConstruction() { this.getConstructedType() instanceof SnakeYamlSafeConstructor }
}
/**
* The class `org.yaml.snakeyaml.Yaml`.
*/
class Yaml extends RefType {
Yaml() { this.getAnAncestor().hasQualifiedName("org.yaml.snakeyaml", "Yaml") }
}
private DataFlow::ExprNode yamlClassInstanceExprArgument(ClassInstanceExpr cie) {
cie.getConstructedType() instanceof Yaml and
result.getExpr() = cie.getArgument(0)
}
private module SafeYamlConstructionFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSnakeYamlConstruction }
predicate isSink(DataFlow::Node sink) { sink = yamlClassInstanceExprArgument(_) }
additional ClassInstanceExpr getSafeYaml() {
SafeYamlConstructionFlow::flowTo(yamlClassInstanceExprArgument(result))
}
}
private module SafeYamlConstructionFlow = DataFlow::Global<SafeYamlConstructionFlowConfig>;
/**
* An instance of `Yaml` that does not allow arbitrary constructor to be called.
*/
private class SafeYaml extends ClassInstanceExpr {
SafeYaml() { SafeYamlConstructionFlowConfig::getSafeYaml() = this }
}
/** A call to a parse method of `Yaml`. */
private class SnakeYamlParse extends MethodCall {
SnakeYamlParse() {
exists(Method m |
m.getDeclaringType() instanceof Yaml and
m.hasName(["compose", "composeAll", "load", "loadAll", "loadAs", "parse"]) and
m = this.getMethod()
)
}
}
private module SafeYamlFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeYaml }
predicate isSink(DataFlow::Node sink) { sink = yamlParseQualifier(_) }
additional DataFlow::ExprNode yamlParseQualifier(SnakeYamlParse syp) {
result.getExpr() = syp.getQualifier()
}
additional SnakeYamlParse getASafeSnakeYamlParse() {
SafeYamlFlow::flowTo(yamlParseQualifier(result))
}
}
private module SafeYamlFlow = DataFlow::Global<SafeYamlFlowConfig>;
/**
* A call to a parse method of `Yaml` that allows arbitrary constructor to be called.
*/
class UnsafeSnakeYamlParse extends SnakeYamlParse {
UnsafeSnakeYamlParse() { not SafeYamlFlowConfig::getASafeSnakeYamlParse() = this }
}