Add remote source of Android intent extra

This commit is contained in:
luchua-bc
2020-06-25 20:20:18 +00:00
committed by Chris Smowton
parent 08bf464437
commit f5ca459795
3 changed files with 60 additions and 0 deletions

View File

@@ -23,6 +23,7 @@ import semmle.code.java.frameworks.spring.SpringWebClient
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 {
@@ -318,3 +319,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

@@ -33,11 +33,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. */
@@ -45,6 +59,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" }
}
/**