Add remote source of Android intent extra

This commit is contained in:
luchua-bc
2020-06-25 20:20:18 +00:00
parent d4c5887122
commit 65e76ab18f
3 changed files with 60 additions and 0 deletions

View File

@@ -20,6 +20,7 @@ import semmle.code.java.frameworks.SpringWeb
import semmle.code.java.frameworks.Guice
import semmle.code.java.frameworks.struts.StrutsActions
import semmle.code.java.frameworks.Thrift
import semmle.code.java.frameworks.android.Android
/** A data flow source of remote user input. */
abstract class RemoteFlowSource extends DataFlow::Node {
@@ -270,3 +271,36 @@ class AndroidIntentInput extends DataFlow::Node {
)
}
}
/**
* Method access to external inputs of `android.content.Intent` object
*/
class IntentGetExtraMethodAccess extends MethodAccess {
IntentGetExtraMethodAccess() {
exists(AndroidComponent ac |
this.getEnclosingCallable().getDeclaringType() = ac and ac.isExported()
) and
(
this.getMethod().getName().regexpMatch("get\\w+Extra") and
this.getMethod().getDeclaringType() instanceof TypeIntent
or
this.getMethod().getName().regexpMatch("get\\w+") and
this.getQualifier().(MethodAccess).getMethod().hasName("getExtras") and
this.getQualifier().(MethodAccess).getMethod().getDeclaringType() instanceof TypeIntent
)
}
}
/**
* Android intent extra source
*/
private class AndroidIntentExtraSource extends RemoteFlowSource {
AndroidIntentExtraSource() {
exists(MethodAccess ma |
ma instanceof IntentGetExtraMethodAccess and
this.asExpr().(VarAccess).getVariable().getAnAssignedValue() = ma
)
}
override string getSourceType() { result = "Android intent extra" }
}

View File

@@ -32,11 +32,25 @@ class AndroidComponent extends Class {
/** An Android activity. */
class AndroidActivity extends AndroidComponent {
AndroidActivity() { this.getASupertype*().hasQualifiedName("android.app", "Activity") }
/** Holds if this Android component is configured as `exported` or has intent filters configured without `exported` explicitly disabled in an `AndroidManifest.xml` file. */
override predicate isExported() {
getAndroidComponentXmlElement().isExported()
or
not getAndroidComponentXmlElement().isNotExported() and hasIntentFilter()
}
}
/** An Android service. */
class AndroidService extends AndroidComponent {
AndroidService() { this.getASupertype*().hasQualifiedName("android.app", "Service") }
/** Holds if this Android component is configured as `exported` or has intent filters configured without `exported` explicitly disabled in an `AndroidManifest.xml` file. */
override predicate isExported() {
getAndroidComponentXmlElement().isExported()
or
not getAndroidComponentXmlElement().isNotExported() and hasIntentFilter()
}
}
/** An Android broadcast receiver. */
@@ -44,6 +58,13 @@ class AndroidBroadcastReceiver extends AndroidComponent {
AndroidBroadcastReceiver() {
this.getASupertype*().hasQualifiedName("android.content", "BroadcastReceiver")
}
/** Holds if this Android component is configured as `exported` or has intent filters configured without `exported` explicitly disabled in an `AndroidManifest.xml` file. */
override predicate isExported() {
getAndroidComponentXmlElement().isExported()
or
not getAndroidComponentXmlElement().isNotExported() and hasIntentFilter()
}
}
/** An Android content provider. */

View File

@@ -137,6 +137,11 @@ class AndroidComponentXmlElement extends XMLElement {
* Holds if the `android:exported` attribute of this component element is `true`.
*/
predicate isExported() { getExportedAttributeValue() = "true" }
/**
* Holds if the `android:exported` attribute of this component element is explicitly set to `false`.
*/
predicate isNotExported() { getExportedAttributeValue() = "false" }
}
/**