mirror of
https://github.com/github/codeql.git
synced 2026-05-05 13:45:19 +02:00
Add Fragment injection query
This commit is contained in:
14
java/ql/lib/semmle/code/java/frameworks/android/Fragment.qll
Normal file
14
java/ql/lib/semmle/code/java/frameworks/android/Fragment.qll
Normal file
@@ -0,0 +1,14 @@
|
||||
import java
|
||||
|
||||
/** The class `android.app.Fragment` */
|
||||
class Fragment extends Class {
|
||||
Fragment() { this.hasQualifiedName("android.app", "Fragment") }
|
||||
}
|
||||
|
||||
/** The method `instantiate` of the class `android.app.Fragment`. */
|
||||
class FragmentInstantiateMethod extends Method {
|
||||
FragmentInstantiateMethod() {
|
||||
this.getDeclaringType() instanceof Fragment and
|
||||
this.hasName("instantiate")
|
||||
}
|
||||
}
|
||||
60
java/ql/lib/semmle/code/java/security/FragmentInjection.qll
Normal file
60
java/ql/lib/semmle/code/java/security/FragmentInjection.qll
Normal file
@@ -0,0 +1,60 @@
|
||||
import java
|
||||
private import semmle.code.java.dataflow.TaintTracking
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.frameworks.android.Android
|
||||
private import semmle.code.java.frameworks.android.Fragment
|
||||
private import semmle.code.java.Reflection
|
||||
|
||||
/**
|
||||
* A sink for Fragment injection vulnerabilities,
|
||||
* that is, method calls that dynamically add Fragments to Activities.
|
||||
*/
|
||||
abstract class FragmentInjectionSink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A unit class for adding additional taint steps.
|
||||
*
|
||||
* Extend this class to add additional taint steps that should apply to `FragmentInjectionTaintConf`.
|
||||
*/
|
||||
class FragmentInjectionAdditionalTaintStep extends Unit {
|
||||
abstract predicate step(DataFlow::Node n1, DataFlow::Node n2);
|
||||
}
|
||||
|
||||
private class FragmentInjectionSinkModels extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
["android.app", "android.support.v4.app", "androidx.fragment.app"] +
|
||||
";FragmentTransaction;true;" +
|
||||
[
|
||||
"add;(Class,Bundle,String);;Argument[0]", "add;(Fragment,String);;Argument[0]",
|
||||
"add;(int,Class,Bundle);;Argument[1]", "add;(int,Fragment);;Argument[1]",
|
||||
"add;(int,Class,Bundle,String);;Argument[1]", "add;(int,Fragment,String);;Argument[1]",
|
||||
"attach;(Fragment);;Argument[0]", "replace;(int,Class,Bundle);;Argument[1]",
|
||||
"replace;(int,Fragment);;Argument[1]", "replace;(int,Class,Bundle,String);;Argument[1]",
|
||||
"replace;(int,Fragment,String);;Argument[1]",
|
||||
] + ";fragment-injection"
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultFragmentInjectionSink extends FragmentInjectionSink {
|
||||
DefaultFragmentInjectionSink() { sinkNode(this, "fragment-injection") }
|
||||
}
|
||||
|
||||
private class DefaultFragmentInjectionAdditionalTaintStep extends FragmentInjectionAdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(ReflectiveClassIdentifierMethodAccess ma |
|
||||
ma.getArgument(0) = n1.asExpr() and ma = n2.asExpr()
|
||||
)
|
||||
or
|
||||
exists(NewInstance ni |
|
||||
ni.getQualifier() = n1.asExpr() and
|
||||
ni = n2.asExpr()
|
||||
)
|
||||
or
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod() instanceof FragmentInstantiateMethod and
|
||||
ma.getArgument(1) = n1.asExpr() and
|
||||
ma = n2.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.FragmentInjection
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe user input
|
||||
* that is used to create Android Fragments dinamically.
|
||||
*/
|
||||
class FragmentInjectionTaintConf extends TaintTracking::Configuration {
|
||||
FragmentInjectionTaintConf() { this = "FragmentInjectionTaintConf" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof FragmentInjectionSink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
any(FragmentInjectionAdditionalTaintStep c).step(n1, n2)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user