Skip to content

Commit 10a3b3b

Browse files
Cover cases in which input type is set via code
1 parent 359d703 commit 10a3b3b

File tree

1 file changed

+67
-2
lines changed

1 file changed

+67
-2
lines changed

java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** Definitions for the keyboard cache query */
22

33
import java
4+
import semmle.code.java.dataflow.DataFlow
45
import semmle.code.java.security.SensitiveActions
56
import semmle.code.xml.AndroidManifest
67

@@ -45,6 +46,62 @@ class AndroidEditableXmlElement extends AndroidLayoutXmlElement {
4546
string getInputType() { result = this.getAttribute("inputType").(AndroidXmlAttribute).getValue() }
4647
}
4748

49+
/** Gets a use of the view that has the given id. */
50+
private Expr getAUseOfId(string id) {
51+
exists(string name, MethodAccess findView, NestedClass r_id, Field id_field |
52+
id = "@+id/" + name and
53+
findView
54+
.getMethod()
55+
.hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) and
56+
r_id.getEnclosingType().hasName("R") and
57+
r_id.hasName("id") and
58+
id_field.getDeclaringType() = r_id and
59+
id_field.hasName(name)
60+
|
61+
DataFlow::localExprFlow(id_field.getAnAccess(), findView.getArgument(0)) and
62+
result = findView
63+
)
64+
}
65+
66+
/** Gets the argument of a use of `setInputType` called on the view with the given id. */
67+
private Expr setInputTypeForId(string id) {
68+
exists(MethodAccess setInputType |
69+
setInputType.getMethod().hasQualifiedName("android.widget", "TextView", "setInputType") and
70+
DataFlow::localExprFlow(getAUseOfId(id), setInputType.getQualifier()) and
71+
result = setInputType.getArgument(0)
72+
)
73+
}
74+
75+
/** Holds if the given field is a constant flag indicating that an input with this type will not be cached. */
76+
private predicate inputTypeFieldNotCached(Field f) {
77+
f.getDeclaringType().hasQualifiedName("android.text", "InputType") and
78+
(
79+
not f.getName().matches("%TEXT%")
80+
or
81+
f.getName().matches("%PASSWORD%")
82+
or
83+
f.getName() = "TYPE_TEXT_FLAG_NO_SUGGESTIONS"
84+
)
85+
}
86+
87+
/** Configuration that finds uses of `setInputType` that for non cached fields. */
88+
private class GoodInputTypeConf extends DataFlow::Configuration {
89+
GoodInputTypeConf() { this = "GoodInputTypeConf" }
90+
91+
override predicate isSource(DataFlow::Node node) {
92+
inputTypeFieldNotCached(node.asExpr().(FieldAccess).getField())
93+
}
94+
95+
override predicate isSink(DataFlow::Node node) { node.asExpr() = setInputTypeForId(_) }
96+
97+
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
98+
exists(OrBitwiseExpr bitOr |
99+
node1.asExpr() = bitOr.getAChildExpr() and
100+
node2.asExpr() = bitOr
101+
)
102+
}
103+
}
104+
48105
/** Gets a regex indicating that an input field may contain sensitive data. */
49106
private string getInputSensitiveInfoRegex() {
50107
result =
@@ -54,7 +111,7 @@ private string getInputSensitiveInfoRegex() {
54111
]
55112
}
56113

57-
/** Holds if input using the given input type may be stored in the keyboard cache. */
114+
/** Holds if input using the given input type (as written in XML) may be stored in the keyboard cache. */
58115
bindingset[ty]
59116
private predicate inputTypeCached(string ty) {
60117
ty.matches("%text%") and
@@ -64,5 +121,13 @@ private predicate inputTypeCached(string ty) {
64121
/** Gets an input field whose contents may be sensitive and may be stored in the keyboard cache. */
65122
AndroidEditableXmlElement getASensitiveCachedInput() {
66123
result.getId().regexpMatch(getInputSensitiveInfoRegex()) and
67-
inputTypeCached(result.getInputType())
124+
(
125+
inputTypeCached(result.getInputType())
126+
or
127+
not exists(result.getInputType()) and
128+
not exists(GoodInputTypeConf conf, DataFlow::Node src, DataFlow::Node sink |
129+
conf.hasFlow(src, sink) and
130+
sink.asExpr() = setInputTypeForId(result.getId())
131+
)
132+
)
68133
}

0 commit comments

Comments
 (0)