6
6
* potentially leading to arbitrary code execution.
7
7
* @problem.severity error
8
8
* @precision high
9
+ * @kind problem
9
10
* @id java/unsafe-reflection
10
11
* @tags security
11
12
* experimental
@@ -16,55 +17,39 @@ import java
16
17
import semmle.code.java.dataflow.DataFlow
17
18
import semmle.code.java.dataflow.TaintTracking
18
19
19
- ControlFlowNode getControlFlowNodeSuccessor ( ControlFlowNode node )
20
- {
21
- result = node .getASuccessor ( )
22
- }
23
20
24
21
MethodAccess getClassLoaderReachableMethodAccess ( DataFlow:: Node node )
25
22
{
26
- exists (
27
- MethodAccess maGetClassLoader , ControlFlowNode cfnGetClassLoader , ControlFlowNode cfnSuccessor |
23
+ exists ( MethodCall maGetClassLoader |
28
24
maGetClassLoader .getCallee ( ) .getName ( ) = "getClassLoader" and
29
25
maGetClassLoader .getQualifier ( ) = node .asExpr ( ) and
30
- maGetClassLoader .getControlFlowNode ( ) = cfnGetClassLoader and
31
- //cfnGetClassLoader.getASuccessor+() = cfnSuccessor and
32
- getControlFlowNodeSuccessor + ( cfnGetClassLoader ) = cfnSuccessor and
33
- cfnSuccessor instanceof MethodAccess and
34
- result = cfnSuccessor .( MethodAccess )
26
+ result = maGetClassLoader .getControlFlowNode ( ) .getASuccessor + ( )
35
27
)
36
28
}
37
29
38
30
MethodAccess getDangerousReachableMethodAccess ( MethodAccess ma )
39
31
{
40
- ( ma .getCallee ( ) .hasName ( "getMethod" ) or
41
- ma .getCallee ( ) .hasName ( "getDeclaredMethod" ) ) and
42
- ( (
43
- exists ( MethodAccess maInvoke |
44
- //ma.getControlFlowNode().getASuccessor*() = maInvoke and
45
- getControlFlowNodeSuccessor + ( ma .getControlFlowNode ( ) ) = maInvoke and
46
- maInvoke .getCallee ( ) .hasName ( "invoke" ) and
47
- result = maInvoke
48
- )
49
- ) or
50
- (
51
- exists ( AssignExpr ae , VarAccess va1 , VarAccess va2 , MethodAccess maInvoke |
52
- ae .getSource ( ) = ma and
53
- ae .getDest ( ) = va1 and
54
- maInvoke .getQualifier ( ) = va2 and
55
- va1 .getVariable ( ) = va2 .getVariable ( ) and
56
- result = maInvoke
57
- )
58
- ) )
32
+ ma .getCallee ( ) .hasName ( [ "getMethod" , "getDeclaredMethod" ] ) and
33
+ (
34
+ result = ma .getControlFlowNode ( ) .getASuccessor * ( ) and
35
+ result .getCallee ( ) .hasName ( "invoke" )
36
+ or
37
+ exists ( AssignExpr ae |
38
+ ae .getSource ( ) = ma and
39
+ ae .getDest ( ) .( VarAccess ) .getVariable ( ) =
40
+ result .getQualifier ( ) .( VarAccess ) .getVariable ( )
41
+ )
42
+ )
59
43
}
60
44
61
45
module SignaturePackageConfig implements DataFlow:: ConfigSig {
62
46
predicate isSource ( DataFlow:: Node source ) {
63
- exists ( MethodAccess maCheckSignatures |
64
- maCheckSignatures .getCallee ( ) .getDeclaringType ( ) .getQualifiedName ( ) = "android.content.pm.PackageManager" and
65
- maCheckSignatures .getCallee ( ) .getName ( ) = "checkSignatures" and
66
- source .asExpr ( ) = maCheckSignatures .getArgument ( 0 )
67
- )
47
+ exists ( MethodCall maCheckSignatures |
48
+ maCheckSignatures
49
+ .getMethod ( )
50
+ .hasQualifiedName ( "android.content.pm" , "PackageManager" , "checkSignatures" ) and
51
+ source .asExpr ( ) = maCheckSignatures .getArgument ( 0 )
52
+ )
68
53
}
69
54
70
55
predicate isSink ( DataFlow:: Node sink ) {
@@ -81,31 +66,20 @@ module SigPkgCfg = TaintTracking::Global<SignaturePackageConfig>;
81
66
82
67
predicate isSignaturesChecked ( MethodAccess maCreatePackageContext )
83
68
{
84
- exists ( DataFlow:: Node source , DataFlow:: Node sink |
85
- SigPkgCfg:: flow ( source , sink ) and
86
- sink .asExpr ( ) = maCreatePackageContext .getArgument ( 0 )
87
- )
69
+ SigPkgCfg:: flowToExpr ( maCreatePackageContext .getArgument ( 0 ) )
88
70
}
89
71
90
- from
91
- MethodAccess maCreatePackageContext ,
92
- LocalVariableDeclExpr lvdePackageContext ,
93
- DataFlow:: Node sinkPackageContext ,
94
- MethodAccess maGetMethod ,
95
- MethodAccess maInvoke
72
+ from
73
+ MethodCall maCreatePackageContext , LocalVariableDeclExpr lvdePackageContext ,
74
+ Expr sinkPackageContext , MethodCall maGetMethod , MethodCall maInvoke
96
75
where
97
- ( maCreatePackageContext .getCallee ( ) .getDeclaringType ( ) .getQualifiedName ( ) = "android.content.ContextWrapper" or
98
- maCreatePackageContext .getCallee ( ) .getDeclaringType ( ) .getQualifiedName ( ) = "android.content.Context" ) and
99
- maCreatePackageContext .getCallee ( ) .getName ( ) = "createPackageContext" and
100
- not isSignaturesChecked ( maCreatePackageContext ) and
101
- lvdePackageContext .getEnclosingStmt ( ) = maCreatePackageContext .getEnclosingStmt ( ) and
102
- TaintTracking:: localTaint ( DataFlow:: exprNode ( lvdePackageContext .getAnAccess ( ) ) , sinkPackageContext ) and
103
- getClassLoaderReachableMethodAccess ( sinkPackageContext ) = maGetMethod and
104
- getDangerousReachableMethodAccess ( maGetMethod ) = maInvoke
105
- select
106
- lvdePackageContext ,
107
- sinkPackageContext ,
108
- maGetMethod ,
109
- maInvoke ,
110
- "Potential arbitary code execution due to class loading without package signature checking."
76
+ maCreatePackageContext
77
+ .getMethod ( )
78
+ .hasQualifiedName ( "android.content" , [ "ContextWrapper" , "Context" ] , "createPackageContext" ) and
79
+ not isSignaturesChecked ( maCreatePackageContext ) and
80
+ lvdePackageContext .getEnclosingStmt ( ) = maCreatePackageContext .getEnclosingStmt ( ) and
81
+ TaintTracking:: localExprTaint ( lvdePackageContext .getAnAccess ( ) , sinkPackageContext ) and
82
+ getClassLoaderReachableMethodCall ( sinkPackageContext ) = maGetMethod and
83
+ getGetMethodMethodCall ( maGetMethod ) = maInvoke
84
+ select maInvoke , "Potential arbitary code execution due to $@ without $@ signature checking." , sinkPackageContext , "class loading" , sinkPackageContext , "package"
111
85
0 commit comments