Skip to content

Commit 7f45a26

Browse files
author
Alvaro Muñoz
committed
Add CodeQL workspace and lock files
1 parent bb00eaf commit 7f45a26

20 files changed

+792
-2
lines changed

codeql-workspace.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
provide:
2+
- java/**/qlpack.yml
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
lockVersion: 1.0.0
3+
dependencies: {}
4+
compiled: false

java/ext/models/codeql-pack.lock.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
lockVersion: 1.0.0
3+
dependencies: {}
4+
compiled: false
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import java
2+
import semmle.code.java.dataflow.FlowSources
3+
import semmle.code.java.dataflow.TaintTracking
4+
import semmle.code.java.dataflow.FlowSteps
5+
import semmle.code.java.dataflow.ExternalFlow
6+
7+
/**
8+
* Taintsteps to enable this -> read flow
9+
* eg: this.field
10+
*/
11+
class FieldReadTaintStep extends TaintTracking::AdditionalTaintStep {
12+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
13+
exists(FieldRead fa |
14+
n1 = DataFlow::getFieldQualifier(fa) and
15+
n2.asExpr() = fa
16+
)
17+
}
18+
}
19+
20+
/**
21+
* Treats a field write as a jump step (one that discards calling context, and supposes that probably at some point a read step takes place)
22+
*/
23+
class FieldTaintStep extends TaintTracking::AdditionalTaintStep {
24+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
25+
// From field write to read
26+
exists(Field f, RefType t |
27+
n1.asExpr() = f.getAnAssignedValue() and
28+
n2.asExpr() = f.getAnAccess() and
29+
n1.asExpr().getEnclosingCallable().getDeclaringType() = t and
30+
n2.asExpr().getEnclosingCallable().getDeclaringType() = t
31+
)
32+
}
33+
}
34+
35+
/**
36+
* Create jump steps for methods connected by the wait/notify pattern
37+
*/
38+
class NotifyWaitTaintStep extends TaintTracking::AdditionalTaintStep {
39+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
40+
exists(
41+
MethodAccess notify, RefType t, MethodAccess wait, SynchronizedStmt notifySync,
42+
SynchronizedStmt waitSync
43+
|
44+
notify.getMethod().getName() = ["notify", "notifyAll"] and
45+
notify.getAnEnclosingStmt() = notifySync and
46+
notifySync.getExpr().getType() = t and
47+
wait.getMethod().getName() = "wait" and
48+
wait.getAnEnclosingStmt() = waitSync and
49+
waitSync.getExpr().getType() = t and
50+
exists(AssignExpr write, FieldAccess read, Field f |
51+
write.getAnEnclosingStmt() = notifySync and
52+
write.getDest().(FieldAccess).getField() = f and
53+
write = n1.asExpr() and
54+
read.getAnEnclosingStmt() = waitSync and
55+
read.getField() = f and
56+
read = n2.asExpr()
57+
)
58+
)
59+
}
60+
}
61+
62+
/**
63+
* Convey taint from the argument of a method call that can throw an exception
64+
* to the exception variable in the correspondinf catch block
65+
*/
66+
class ExceptionTaintStep extends TaintTracking::AdditionalTaintStep {
67+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
68+
exists(Call call, TryStmt t, CatchClause c, MethodAccess gm |
69+
call.getEnclosingStmt().getEnclosingStmt*() = t.getBlock() and
70+
t.getACatchClause() = c and
71+
(
72+
call.getCallee().getAThrownExceptionType().getASubtype*() = c.getACaughtType() or
73+
c.getACaughtType().getASupertype*() instanceof TypeRuntimeException
74+
) and
75+
c.getVariable().getAnAccess() = gm.getQualifier() and
76+
gm.getMethod().getName().regexpMatch("get(Localized)?Message|toString") and
77+
n1.asExpr() = call.getAnArgument() and
78+
n2.asExpr() = gm
79+
)
80+
}
81+
}
82+
83+
/**
84+
* Convey taint from globally tainted objects to their fields
85+
*/
86+
private class GetterTaintStep extends TaintTracking::AdditionalTaintStep {
87+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
88+
exists(MethodAccess ma, Method m |
89+
ma.getMethod() = m and
90+
m.getName().matches("get%") and
91+
m.getNumberOfParameters() = 0 and
92+
n1.asExpr() = ma.getQualifier() and
93+
n2.asExpr() = ma
94+
)
95+
}
96+
}
97+
/*
98+
* private class SetterTaintStep extends TaintTracking::AdditionalTaintStep {
99+
* override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
100+
* exists(MethodAccess ma, Method m |
101+
* ma.getMethod() = m and
102+
* m.getName().matches("set%") and
103+
* m.getNumberOfParameters() = 1 and
104+
* ma.getEnclosingCallable().getDeclaringType().getName().matches("%Factory") and
105+
* n1.asExpr() = ma.getArgument(0) and
106+
* n2.asExpr() = ma.getQualifier()
107+
* )
108+
* }
109+
* }
110+
*
111+
* class GlobalSanitizer extends TaintTracking::Sanitizer {
112+
* override predicate sanitize(DataFlow::Node node) {
113+
* node.asExpr().(MethodAccess).getMethod().hasName("getInputStream") or
114+
* node.asExpr().(MethodAccess).getMethod().hasName("getHostName")
115+
* }
116+
* }
117+
*/
118+
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import java
2+
import semmle.code.java.dataflow.FlowSteps
3+
import semmle.code.java.dataflow.FlowSources
4+
5+
module Dubbo {
6+
class ConfigListener extends RemoteFlowSource {
7+
ConfigListener() {
8+
exists(Method m, Parameter p, Interface c |
9+
this.asParameter() = p and
10+
m.getAParameter() = p and
11+
m.isPublic() and
12+
c = m.getDeclaringType().getASourceSupertype*() and
13+
c.getName() = ["NotifyListener", "ConfigurationListener"] and
14+
m.overridesOrInstantiates(c.getAMethod()) and
15+
not m.getDeclaringType().getLocation().getFile().getAbsolutePath().matches("%/src/test/%")
16+
)
17+
}
18+
19+
override string getSourceType() { result = "Config Listener Source" }
20+
}
21+
22+
class CodecSupportGetPayload extends TaintTracking::AdditionalTaintStep {
23+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
24+
exists(MethodAccess ma |
25+
ma.getMethod()
26+
.getDeclaringType()
27+
.hasQualifiedName("org.apache.dubbo.remoting.transport", "CodecSupport") and
28+
ma.getMethod().hasName("getPayload") and
29+
n1.asExpr() = ma.getArgument(0) and
30+
n2.asExpr() = ma
31+
)
32+
}
33+
}
34+
35+
class CodecSupportDeserialize extends TaintTracking::AdditionalTaintStep {
36+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
37+
exists(MethodAccess ma |
38+
ma.getMethod()
39+
.getDeclaringType()
40+
.hasQualifiedName("org.apache.dubbo.remoting.transport", "CodecSupport") and
41+
ma.getMethod().hasName("deserialize") and
42+
n1.asExpr() = ma.getArgument(1) and
43+
n2.asExpr() = ma
44+
)
45+
}
46+
}
47+
48+
class ChannelBufferInputStreamInit extends TaintTracking::AdditionalTaintStep {
49+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
50+
exists(ClassInstanceExpr ma |
51+
ma.getConstructedType()
52+
.hasQualifiedName("org.apache.dubbo.remoting.buffer", "ChannelBufferInputStream") and
53+
n1.asExpr() = ma.getArgument(0) and
54+
n2.asExpr() = ma
55+
)
56+
}
57+
}
58+
59+
class ChannelBuffer_ThisReturn_TaintStep extends TaintTracking::AdditionalTaintStep {
60+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
61+
exists(MethodAccess ma |
62+
ma.getMethod()
63+
.getDeclaringType()
64+
.getASourceSupertype*()
65+
.hasQualifiedName("org.apache.dubbo.remoting.buffer", "ChannelBuffer") and
66+
ma.getMethod().getName().matches(["array", "getByte", "readByte", "toByteBuffer"]) and
67+
n1.asExpr() = ma.getQualifier() and
68+
n2.asExpr() = ma
69+
)
70+
}
71+
}
72+
73+
class ChannelBuffer_ThisArg1_TaintStep extends TaintTracking::AdditionalTaintStep {
74+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
75+
exists(MethodAccess ma |
76+
ma.getMethod()
77+
.getDeclaringType()
78+
.getASourceSupertype*()
79+
.hasQualifiedName("org.apache.dubbo.remoting.buffer", "ChannelBuffer") and
80+
ma.getMethod().getName().matches("getBytes") and
81+
n1.asExpr() = ma.getQualifier() and
82+
n2.asExpr() = ma.getArgument(1)
83+
)
84+
}
85+
}
86+
87+
class ChannelBuffer_ThisArg0_TaintStep extends TaintTracking::AdditionalTaintStep {
88+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
89+
exists(MethodAccess ma |
90+
ma.getMethod()
91+
.getDeclaringType()
92+
.getASourceSupertype*()
93+
.hasQualifiedName("org.apache.dubbo.remoting.buffer", "ChannelBuffer") and
94+
ma.getMethod().getName().matches("readBytes") and
95+
n1.asExpr() = ma.getQualifier() and
96+
n2.asExpr() = ma.getArgument(0)
97+
)
98+
}
99+
}
100+
101+
class ChannelBuffer_ArgThis1_TaintStep extends TaintTracking::AdditionalTaintStep {
102+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
103+
exists(MethodAccess ma |
104+
ma.getMethod()
105+
.getDeclaringType()
106+
.getASourceSupertype*()
107+
.hasQualifiedName("org.apache.dubbo.remoting.buffer", "ChannelBuffer") and
108+
ma.getMethod().getName().matches("setBytes") and
109+
n1.asExpr() = ma.getArgument(1) and
110+
n2.asExpr() = ma.getQualifier()
111+
)
112+
}
113+
}
114+
115+
class ChannelBuffer_ArgThis0_TaintStep extends TaintTracking::AdditionalTaintStep {
116+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
117+
exists(MethodAccess ma |
118+
ma.getMethod()
119+
.getDeclaringType()
120+
.getASourceSupertype*()
121+
.hasQualifiedName("org.apache.dubbo.remoting.buffer", "ChannelBuffer") and
122+
ma.getMethod().getName().matches("writeBytes") and
123+
n1.asExpr() = ma.getArgument(1) and
124+
n2.asExpr() = ma.getQualifier()
125+
)
126+
}
127+
}
128+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import java
2+
import semmle.code.java.dataflow.FlowSources
3+
4+
class GrpcRequest extends RemoteFlowSource {
5+
GrpcRequest() {
6+
exists(Method m |
7+
m.getName() = "handleRequest" and
8+
m.getDeclaringType()
9+
.getASourceSupertype*()
10+
.hasQualifiedName("com.alipay.sofa.jraft.rpc", "RpcProcessor") and
11+
m.getParameter(1) = this.asParameter()
12+
)
13+
}
14+
15+
override string getSourceType() { result = "gRPC Form Field" }
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import java
2+
import semmle.code.java.dataflow.FlowSources
3+
4+
class OneDevEditableField extends RemoteFlowSource {
5+
OneDevEditableField() {
6+
exists(Method getter, Method setter |
7+
getter
8+
.getAnAnnotation()
9+
.getType()
10+
.hasQualifiedName("io.onedev.server.web.editable.annotation", "Editable") and
11+
getter.getDeclaringType() = setter.getDeclaringType() and
12+
getter.getName().matches("get%") and
13+
setter.getName().matches("set%") and
14+
setter.getName().substring(1, setter.getName().length()) =
15+
getter.getName().substring(1, getter.getName().length()) and
16+
setter.getAParameter() = this.asParameter()
17+
)
18+
}
19+
20+
override string getSourceType() { result = "OneDev Form Field" }
21+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import semmle.code.java.dataflow.TaintTracking
2+
3+
module GuavaCache {
4+
class TypeCacheBuilder extends RefType {
5+
TypeCacheBuilder() { this.hasQualifiedName("com.google.common.cache", "CacheBuilder") }
6+
}
7+
8+
class TypeLoadingCache extends RefType {
9+
TypeLoadingCache() { this.hasQualifiedName("com.google.common.cache", "LoadingCache") }
10+
}
11+
12+
class GetFromCacheMethod extends Method {
13+
GetFromCacheMethod() {
14+
this.getDeclaringType().getASourceSupertype*() instanceof TypeLoadingCache and
15+
(this.getName() = "get" or this.getName() = "getUnchecked")
16+
}
17+
}
18+
19+
class BuildCacheLoaderMethod extends Method {
20+
BuildCacheLoaderMethod() {
21+
this.getDeclaringType().getASourceSupertype*() instanceof TypeCacheBuilder and
22+
this.getName() = "build"
23+
}
24+
}
25+
26+
/**
27+
* Taint step from the `get` operation to the loader
28+
* CacheLoader<String, String> loader;
29+
* loader = new CacheLoader<String, String>() {
30+
*
31+
* @Override public String load(String key) {
32+
* return key.toUpperCase(); // N2
33+
* }
34+
* };
35+
* LoadingCache<String, String> cache;
36+
* cache = CacheBuilder.newBuilder().build(loader);
37+
* assertEquals("HELLO", cache.getUnchecked("doo")); // N1
38+
*/
39+
class LoadCacheItemTaintStep extends TaintTracking::AdditionalTaintStep {
40+
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
41+
exists(MethodAccess ma1, MethodAccess ma2, VarAccess va |
42+
ma1.getMethod() instanceof GetFromCacheMethod and
43+
ma2.getMethod() instanceof BuildCacheLoaderMethod and
44+
exists(Method m |
45+
ma2.getArgument(0).getType().(RefType).getAMethod() = m and
46+
m.getName() = "load" and
47+
m.getAParameter() = va.getVariable() and
48+
n1.asExpr() = ma1.getArgument(0) and
49+
n2.asExpr() = va
50+
)
51+
)
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)