mirror of
https://github.com/github/codeql.git
synced 2026-04-25 00:35:20 +02:00
Add the Intent parameter of onActivityResult as a source
This commit is contained in:
@@ -17,6 +17,7 @@ import semmle.code.java.frameworks.android.WebView
|
||||
import semmle.code.java.frameworks.JaxWS
|
||||
import semmle.code.java.frameworks.javase.WebSocket
|
||||
import semmle.code.java.frameworks.android.Android
|
||||
import semmle.code.java.frameworks.android.OnActivityResultSource
|
||||
import semmle.code.java.frameworks.android.Intent
|
||||
import semmle.code.java.frameworks.play.Play
|
||||
import semmle.code.java.frameworks.spring.SpringWeb
|
||||
@@ -264,3 +265,13 @@ class ExportedAndroidContentProviderInput extends RemoteFlowSource, AndroidConte
|
||||
|
||||
override string getSourceType() { result = "Exported Android content provider source" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The data Intent parameter in the `onActivityResult` method in an Activity or Fragment that
|
||||
* calls `startActivityForResult` with an implicit Intent.
|
||||
*/
|
||||
class OnActivityResultIntentSource extends OnActivityResultIncomingIntent, RemoteFlowSource {
|
||||
OnActivityResultIntentSource() { isRemoteSource() }
|
||||
|
||||
override string getSourceType() { result = "Android onActivityResult incoming Intent" }
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
/** Provides classes and predicates to track Android fragments. */
|
||||
|
||||
import java
|
||||
|
||||
/** The class `android.app.Fragment` */
|
||||
class Fragment extends Class {
|
||||
Fragment() { this.hasQualifiedName("android.app", "Fragment") }
|
||||
/** An Android Fragment. */
|
||||
class AndroidFragment extends Class {
|
||||
AndroidFragment() { this.getASupertype*().hasQualifiedName("android.app", "Fragment") }
|
||||
}
|
||||
|
||||
/** The method `instantiate` of the class `android.app.Fragment`. */
|
||||
class FragmentInstantiateMethod extends Method {
|
||||
FragmentInstantiateMethod() {
|
||||
this.getDeclaringType() instanceof Fragment and
|
||||
this.getDeclaringType() instanceof AndroidFragment and
|
||||
this.hasName("instantiate")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/** Provides a remote flow source for Android's `Activity.onActivityResult` method. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.DataFlow5
|
||||
private import semmle.code.java.frameworks.android.Android
|
||||
private import semmle.code.java.frameworks.android.Fragment
|
||||
private import semmle.code.java.frameworks.android.Intent
|
||||
|
||||
/**
|
||||
* The data Intent parameter in the `onActivityResult` method.
|
||||
*/
|
||||
class OnActivityResultIncomingIntent extends DataFlow::Node {
|
||||
OnActivityResultIncomingIntent() {
|
||||
exists(Method onActivityResult |
|
||||
onActivityResult.getDeclaringType() instanceof ActivityOrFragment and
|
||||
onActivityResult.hasName("onActivityResult") and
|
||||
this.asParameter() = onActivityResult.getParameter(2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node is a remote flow source.
|
||||
*
|
||||
* This is only a source when the Activity or Fragment that implements `onActivityResult` is
|
||||
* also using an implicit Intent to start another Activity with `startActivityForResult`. This
|
||||
* means that a malicious application can intercept it to start itself and return an arbitrary
|
||||
* Intent to `onActivityResult`.
|
||||
*/
|
||||
predicate isRemoteSource() {
|
||||
exists(ImplicitStartActivityForResultConf conf, DataFlow::Node sink |
|
||||
conf.hasFlowTo(sink) and
|
||||
DataFlow::getInstanceArgument(sink.asExpr().(Argument).getCall()).getType() =
|
||||
this.getEnclosingCallable().getDeclaringType()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow configuration for implicit intents being used in `startActivityForResult`.
|
||||
*/
|
||||
private class ImplicitStartActivityForResultConf extends DataFlow5::Configuration {
|
||||
ImplicitStartActivityForResultConf() { this = "ImplicitStartActivityForResultConf" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(ClassInstanceExpr cc |
|
||||
cc.getConstructedType() instanceof TypeIntent and source.asExpr() = cc
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(ActivityOrFragment actOrFrag, MethodAccess startActivityForResult |
|
||||
startActivityForResult.getMethod().hasName("startActivityForResult") and
|
||||
startActivityForResult.getEnclosingCallable() = actOrFrag.getACallable() and
|
||||
sink.asExpr() = startActivityForResult.getArgument(0)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isBarrier(DataFlow::Node barrier) {
|
||||
barrier instanceof ExplicitIntentSanitizer
|
||||
}
|
||||
}
|
||||
|
||||
/** An Android Activity or Fragment. */
|
||||
private class ActivityOrFragment extends Class {
|
||||
ActivityOrFragment() {
|
||||
this instanceof AndroidActivity or
|
||||
this instanceof AndroidFragment
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user