1
1
/**
2
2
* @name Unsafe deserialization with RMI.
3
- * @description TBD
3
+ * @description Java RMI uses native Java serialization mechanism.
4
+ * If a registered remote object has a method that takes a complex object,
5
+ * an attacker can take advantage of unsafe Java deserialization mechanism.
6
+ * In the worst case, it results in remote code execution.
4
7
* @kind problem
5
8
* @problem.severity error
6
9
* @precision high
@@ -16,13 +19,22 @@ private class ObjectInputStream extends RefType {
16
19
ObjectInputStream ( ) { hasQualifiedName ( "java.io" , "ObjectInputStream" ) }
17
20
}
18
21
22
+ /**
23
+ * A method that binds a name to a remote object.
24
+ */
19
25
private class BindMethod extends Method {
20
26
BindMethod ( ) {
21
- getDeclaringType ( ) .hasQualifiedName ( "java.rmi" , "Naming" ) and
27
+ (
28
+ getDeclaringType ( ) .hasQualifiedName ( "java.rmi" , "Naming" ) or
29
+ getDeclaringType ( ) .hasQualifiedName ( "java.rmi.registry" , "Registry" )
30
+ ) and
22
31
hasName ( [ "bind" , "rebind" ] )
23
32
}
24
33
}
25
34
35
+ /**
36
+ * Looks for a vulnerable method in a `Remote` object.
37
+ */
26
38
private Method getVulnerableMethod ( Type type ) {
27
39
type .( RefType ) .getASupertype * ( ) instanceof TypeRemote and
28
40
exists ( Method m , Type parameterType |
@@ -35,6 +47,9 @@ private Method getVulnerableMethod(Type type) {
35
47
)
36
48
}
37
49
50
+ /**
51
+ * A method call that registers a remote object that has a vulnerable method.
52
+ */
38
53
private class UnsafeRmiBinding extends MethodAccess {
39
54
Method vulnerableMethod ;
40
55
@@ -46,7 +61,5 @@ private class UnsafeRmiBinding extends MethodAccess {
46
61
Method getVulnerableMethod ( ) { result = vulnerableMethod }
47
62
}
48
63
49
- // TODO: Cover Registry.bind() and rebind() -- test these sinks first
50
-
51
64
from UnsafeRmiBinding call
52
65
select call , "Unsafe deserialization with RMI in '" + call .getVulnerableMethod ( ) + "' method"
0 commit comments