mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
Refactor CWE-940/AndroidIntentRedirection
This commit is contained in:
@@ -8,9 +8,11 @@ import semmle.code.java.dataflow.TaintTracking3
|
|||||||
import semmle.code.java.security.AndroidIntentRedirection
|
import semmle.code.java.security.AndroidIntentRedirection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `IntentRedirectionFlow` instead.
|
||||||
|
*
|
||||||
* A taint tracking configuration for tainted Intents being used to start Android components.
|
* A taint tracking configuration for tainted Intents being used to start Android components.
|
||||||
*/
|
*/
|
||||||
class IntentRedirectionConfiguration extends TaintTracking::Configuration {
|
deprecated class IntentRedirectionConfiguration extends TaintTracking::Configuration {
|
||||||
IntentRedirectionConfiguration() { this = "IntentRedirectionConfiguration" }
|
IntentRedirectionConfiguration() { this = "IntentRedirectionConfiguration" }
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
@@ -26,31 +28,44 @@ class IntentRedirectionConfiguration extends TaintTracking::Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private module IntentRedirectionConfig implements DataFlow::ConfigSig {
|
||||||
|
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
|
|
||||||
|
predicate isSink(DataFlow::Node sink) { sink instanceof IntentRedirectionSink }
|
||||||
|
|
||||||
|
predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof IntentRedirectionSanitizer }
|
||||||
|
|
||||||
|
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
|
any(IntentRedirectionAdditionalTaintStep c).step(node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A taint tracking configuration for tainted Intents being used to start Android components. */
|
||||||
|
module IntentRedirectionFlow = TaintTracking::Make<IntentRedirectionConfig>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sanitizer for sinks that receive the original incoming Intent,
|
* A sanitizer for sinks that receive the original incoming Intent,
|
||||||
* since its component cannot be arbitrarily set.
|
* since its component cannot be arbitrarily set.
|
||||||
*/
|
*/
|
||||||
private class OriginalIntentSanitizer extends IntentRedirectionSanitizer {
|
private class OriginalIntentSanitizer extends IntentRedirectionSanitizer {
|
||||||
OriginalIntentSanitizer() { any(SameIntentBeingRelaunchedConfiguration c).hasFlowTo(this) }
|
OriginalIntentSanitizer() { SameIntentBeingRelaunchedFlow::hasFlowTo(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data flow configuration used to discard incoming Intents
|
* Data flow configuration used to discard incoming Intents
|
||||||
* flowing directly to sinks that start Android components.
|
* flowing directly to sinks that start Android components.
|
||||||
*/
|
*/
|
||||||
private class SameIntentBeingRelaunchedConfiguration extends DataFlow2::Configuration {
|
private module SameIntentBeingRelaunchedConfig implements DataFlow::ConfigSig {
|
||||||
SameIntentBeingRelaunchedConfiguration() { this = "SameIntentBeingRelaunchedConfiguration" }
|
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
predicate isSink(DataFlow::Node sink) { sink instanceof IntentRedirectionSink }
|
||||||
|
|
||||||
override predicate isSink(DataFlow::Node sink) { sink instanceof IntentRedirectionSink }
|
predicate isBarrier(DataFlow::Node barrier) {
|
||||||
|
|
||||||
override predicate isBarrier(DataFlow::Node barrier) {
|
|
||||||
// Don't discard the Intent if its original component is tainted
|
// Don't discard the Intent if its original component is tainted
|
||||||
barrier instanceof IntentWithTaintedComponent
|
barrier instanceof IntentWithTaintedComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
// Intents being built with the copy constructor from the original Intent are discarded too
|
// Intents being built with the copy constructor from the original Intent are discarded too
|
||||||
exists(ClassInstanceExpr cie |
|
exists(ClassInstanceExpr cie |
|
||||||
cie.getConstructedType() instanceof TypeIntent and
|
cie.getConstructedType() instanceof TypeIntent and
|
||||||
@@ -61,12 +76,14 @@ private class SameIntentBeingRelaunchedConfiguration extends DataFlow2::Configur
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private module SameIntentBeingRelaunchedFlow = DataFlow::Make<SameIntentBeingRelaunchedConfig>;
|
||||||
|
|
||||||
/** An `Intent` with a tainted component. */
|
/** An `Intent` with a tainted component. */
|
||||||
private class IntentWithTaintedComponent extends DataFlow::Node {
|
private class IntentWithTaintedComponent extends DataFlow::Node {
|
||||||
IntentWithTaintedComponent() {
|
IntentWithTaintedComponent() {
|
||||||
exists(IntentSetComponent setExpr, TaintedIntentComponentConf conf |
|
exists(IntentSetComponent setExpr |
|
||||||
setExpr.getQualifier() = this.asExpr() and
|
setExpr.getQualifier() = this.asExpr() and
|
||||||
conf.hasFlowTo(DataFlow::exprNode(setExpr.getSink()))
|
TaintedIntentComponentFlow::hasFlowTo(DataFlow::exprNode(setExpr.getSink()))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,16 +91,16 @@ private class IntentWithTaintedComponent extends DataFlow::Node {
|
|||||||
/**
|
/**
|
||||||
* A taint tracking configuration for tainted data flowing to an `Intent`'s component.
|
* A taint tracking configuration for tainted data flowing to an `Intent`'s component.
|
||||||
*/
|
*/
|
||||||
private class TaintedIntentComponentConf extends TaintTracking3::Configuration {
|
private module TaintedIntentComponentConfig implements DataFlow::ConfigSig {
|
||||||
TaintedIntentComponentConf() { this = "TaintedIntentComponentConf" }
|
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
predicate isSink(DataFlow::Node sink) {
|
||||||
|
|
||||||
override predicate isSink(DataFlow::Node sink) {
|
|
||||||
any(IntentSetComponent setComponent).getSink() = sink.asExpr()
|
any(IntentSetComponent setComponent).getSink() = sink.asExpr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private module TaintedIntentComponentFlow = TaintTracking::Make<TaintedIntentComponentConfig>;
|
||||||
|
|
||||||
/** A call to a method that changes the component of an `Intent`. */
|
/** A call to a method that changes the component of an `Intent`. */
|
||||||
private class IntentSetComponent extends MethodAccess {
|
private class IntentSetComponent extends MethodAccess {
|
||||||
int sinkArg;
|
int sinkArg;
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
|
|
||||||
import java
|
import java
|
||||||
import semmle.code.java.security.AndroidIntentRedirectionQuery
|
import semmle.code.java.security.AndroidIntentRedirectionQuery
|
||||||
import DataFlow::PathGraph
|
import IntentRedirectionFlow::PathGraph
|
||||||
|
|
||||||
from DataFlow::PathNode source, DataFlow::PathNode sink, IntentRedirectionConfiguration conf
|
from IntentRedirectionFlow::PathNode source, IntentRedirectionFlow::PathNode sink
|
||||||
where conf.hasFlowPath(source, sink)
|
where IntentRedirectionFlow::hasFlowPath(source, sink)
|
||||||
select sink.getNode(), source, sink,
|
select sink.getNode(), source, sink,
|
||||||
"Arbitrary Android activities or services can be started from a $@.", source.getNode(),
|
"Arbitrary Android activities or services can be started from a $@.", source.getNode(),
|
||||||
"user-provided value"
|
"user-provided value"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class HasAndroidIntentRedirectionTest extends InlineExpectationsTest {
|
|||||||
|
|
||||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
tag = "hasAndroidIntentRedirection" and
|
tag = "hasAndroidIntentRedirection" and
|
||||||
exists(DataFlow::Node sink, IntentRedirectionConfiguration conf | conf.hasFlowTo(sink) |
|
exists(DataFlow::Node sink | IntentRedirectionFlow::hasFlowTo(sink) |
|
||||||
sink.getLocation() = location and
|
sink.getLocation() = location and
|
||||||
element = sink.toString() and
|
element = sink.toString() and
|
||||||
value = ""
|
value = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user