Skip to content

Commit a811ab3

Browse files
committed
Add ContentProvider sources
1 parent 4adb0c7 commit a811ab3

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

java/ql/lib/semmle/code/java/dataflow/FlowSources.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,17 @@ class ExportedAndroidIntentInput extends RemoteFlowSource, AndroidIntentInput {
247247

248248
override string getSourceType() { result = "Exported Android intent source" }
249249
}
250+
251+
/** A parameter of an entry-point method declared in a `ContentProvider` class. */
252+
class AndroidContentProviderInput extends DataFlow::Node {
253+
AndroidContentProvider declaringType;
254+
255+
AndroidContentProviderInput() { sourceNode(this, "contentprovider") }
256+
}
257+
258+
/** A parameter of an entry-point method declared in an exported `ContentProvider` class. */
259+
class ExportedAndroidContentProviderInput extends RemoteFlowSource, AndroidContentProviderInput {
260+
ExportedAndroidContentProviderInput() { declaringType.isExported() }
261+
262+
override string getSourceType() { result = "Exported Android content provider source" }
263+
}

java/ql/lib/semmle/code/java/frameworks/android/Android.qll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ class AndroidContentProvider extends ExportableAndroidComponent {
7272
AndroidContentProvider() {
7373
this.getASupertype*().hasQualifiedName("android.content", "ContentProvider")
7474
}
75+
76+
/**
77+
* Holds if this content provider requires read and write permissions
78+
* in an `AndroidManifest.xml` file.
79+
*/
80+
predicate requiresPermissions() {
81+
getAndroidComponentXmlElement().(AndroidProviderXmlElement).requiresPermissions()
82+
}
7583
}
7684

7785
/** An Android content resolver. */
@@ -148,3 +156,39 @@ private class UriModel extends SummaryModelCsv {
148156
]
149157
}
150158
}
159+
160+
private class ContentProviderSourceModels extends SourceModelCsv {
161+
override predicate row(string row) {
162+
row =
163+
[
164+
// ContentInterface models are here for backwards compatibility (it was removed in API 28)
165+
"android.content;ContentInterface;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
166+
"android.content;ContentProvider;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
167+
"android.content;ContentProvider;true;call;(String,String,Bundle);;Parameter[0..2];contentprovider",
168+
"android.content;ContentProvider;true;delete;(Uri,String,String[]);;Parameter[0..2];contentprovider",
169+
"android.content;ContentInterface;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
170+
"android.content;ContentProvider;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
171+
"android.content;ContentInterface;true;getType;(Uri);;Parameter[0];contentprovider",
172+
"android.content;ContentProvider;true;getType;(Uri);;Parameter[0];contentprovider",
173+
"android.content;ContentInterface;true;insert;(Uri,ContentValues,Bundle);;Parameter[0];contentprovider",
174+
"android.content;ContentProvider;true;insert;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
175+
"android.content;ContentProvider;true;insert;(Uri,ContentValues);;Parameter[0..1];contentprovider",
176+
"android.content;ContentInterface;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
177+
"android.content;ContentProvider;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
178+
"android.content;ContentProvider;true;openAssetFile;(Uri,String);;Parameter[0];contentprovider",
179+
"android.content;ContentInterface;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
180+
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
181+
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle);;Parameter[0..2];contentprovider",
182+
"android.content;ContentInterface;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
183+
"android.content;ContentProvider;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
184+
"android.content;ContentProvider;true;openFile;(Uri,String);;Parameter[0];contentprovider",
185+
"android.content;ContentInterface;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
186+
"android.content;ContentProvider;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
187+
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Parameter[0..4];contentprovider",
188+
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Parameter[0..4];contentprovider",
189+
"android.content;ContentInterface;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
190+
"android.content;ContentProvider;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
191+
"android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Parameter[0..3];contentprovider"
192+
]
193+
}
194+
}

java/ql/lib/semmle/code/xml/AndroidManifest.qll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,47 @@ class AndroidReceiverXmlElement extends AndroidComponentXmlElement {
7979
*/
8080
class AndroidProviderXmlElement extends AndroidComponentXmlElement {
8181
AndroidProviderXmlElement() { this.getName() = "provider" }
82+
83+
/**
84+
* Holds if this provider element has explicitly set a value for either its
85+
* `android:permission` attribute or its `android:readPermission` and `android:writePermission`
86+
* attributes.
87+
*/
88+
predicate requiresPermissions() {
89+
this.getAnAttribute().(AndroidPermissionXmlAttribute).isFull()
90+
or
91+
this.getAnAttribute().(AndroidPermissionXmlAttribute).isWrite() and
92+
this.getAnAttribute().(AndroidPermissionXmlAttribute).isRead()
93+
}
94+
}
95+
96+
/**
97+
* The attribute `android:perrmission`, `android:readPermission`, or `android:writePermission`.
98+
*/
99+
class AndroidPermissionXmlAttribute extends XMLAttribute {
100+
AndroidPermissionXmlAttribute() {
101+
this.getNamespace().getPrefix() = "android" and
102+
this.getName() = ["permission", "readPermission", "writePermission"]
103+
}
104+
105+
/** Holds if this is an `android:permission` attribute. */
106+
predicate isFull() { this.getName() = "permission" }
107+
108+
/** Holds if this is an `android:readPermission` attribute. */
109+
predicate isRead() { this.getName() = "readPermission" }
110+
111+
/** Holds if this is an `android:writePermission` attribute. */
112+
predicate isWrite() { this.getName() = "writePermission" }
113+
}
114+
115+
/**
116+
* The `<path-permission`> element of a `<provider>` in an Android manifest file.
117+
*/
118+
class AndroidPathPermissionXmlElement extends XMLElement {
119+
AndroidPathPermissionXmlElement() {
120+
this.getParent() instanceof AndroidProviderXmlElement and
121+
this.hasName("path-permission")
122+
}
82123
}
83124

84125
/**

0 commit comments

Comments
 (0)