Merge pull request #12541 from egregius313/egregius313/refactor-queries-to-new-dataflow-api

Java: Refactor more queries to the new DataFlow module API
This commit is contained in:
Edward Minnix III
2023-03-20 12:24:26 -04:00
committed by GitHub
20 changed files with 254 additions and 170 deletions

View File

@@ -18,32 +18,33 @@ import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.security.PathCreation
import semmle.code.java.security.PathSanitizer
import DataFlow::PathGraph
import TaintedPathCommon
class TaintedPathLocalConfig extends TaintTracking::Configuration {
TaintedPathLocalConfig() { this = "TaintedPathLocalConfig" }
module TaintedPathLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(PathCreation p).getAnInput()
or
sinkNode(sink, "create-file")
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
predicate isBarrier(DataFlow::Node sanitizer) {
sanitizer.getType() instanceof BoxedType or
sanitizer.getType() instanceof PrimitiveType or
sanitizer.getType() instanceof NumberType or
sanitizer instanceof PathInjectionSanitizer
}
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(TaintedPathAdditionalTaintStep s).step(n1, n2)
}
}
module TaintedPathLocalFlow = TaintTracking::Make<TaintedPathLocalConfig>;
import TaintedPathLocalFlow::PathGraph
/**
* Gets the data-flow node at which to report a path ending at `sink`.
*
@@ -52,13 +53,13 @@ class TaintedPathLocalConfig extends TaintTracking::Configuration {
* continue to report there; otherwise we report directly at `sink`.
*/
DataFlow::Node getReportingNode(DataFlow::Node sink) {
any(TaintedPathLocalConfig c).hasFlowTo(sink) and
TaintedPathLocalFlow::hasFlowTo(sink) and
if exists(PathCreation pc | pc.getAnInput() = sink.asExpr())
then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr())
else result = sink
}
from DataFlow::PathNode source, DataFlow::PathNode sink, TaintedPathLocalConfig conf
where conf.hasFlowPath(source, sink)
from TaintedPathLocalFlow::PathNode source, TaintedPathLocalFlow::PathNode sink
where TaintedPathLocalFlow::hasFlowPath(source, sink)
select getReportingNode(sink.getNode()), source, sink, "This path depends on a $@.",
source.getNode(), "user-provided value"

View File

@@ -17,8 +17,6 @@ import semmle.code.java.controlflow.Guards
import semmle.code.java.dataflow.SSA
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.PathSanitizer
import DataFlow
import PathGraph
private import semmle.code.java.dataflow.ExternalFlow
/**
@@ -36,18 +34,20 @@ class ArchiveEntryNameMethod extends Method {
}
}
class ZipSlipConfiguration extends TaintTracking::Configuration {
ZipSlipConfiguration() { this = "ZipSlip" }
override predicate isSource(Node source) {
module ZipSlipConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(MethodAccess).getMethod() instanceof ArchiveEntryNameMethod
}
override predicate isSink(Node sink) { sink instanceof FileCreationSink }
predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
override predicate isSanitizer(Node node) { node instanceof PathInjectionSanitizer }
predicate isBarrier(DataFlow::Node node) { node instanceof PathInjectionSanitizer }
}
module ZipSlipFlow = TaintTracking::Make<ZipSlipConfig>;
import ZipSlipFlow::PathGraph
/**
* A sink that represents a file creation, such as a file write, copy or move operation.
*/
@@ -55,8 +55,8 @@ private class FileCreationSink extends DataFlow::Node {
FileCreationSink() { sinkNode(this, "create-file") }
}
from PathNode source, PathNode sink
where any(ZipSlipConfiguration c).hasFlowPath(source, sink)
from ZipSlipFlow::PathNode source, ZipSlipFlow::PathNode sink
where ZipSlipFlow::hasFlowPath(source, sink)
select source.getNode(), source, sink,
"Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(),
"file system operation"

View File

@@ -14,9 +14,9 @@
import java
import semmle.code.java.dataflow.FlowSources
import LdapInjectionLib
import DataFlow::PathGraph
import LdapInjectionFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, LdapInjectionFlowConfig conf
where conf.hasFlowPath(source, sink)
from LdapInjectionFlow::PathNode source, LdapInjectionFlow::PathNode sink
where LdapInjectionFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "This LDAP query depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -1,21 +1,20 @@
import java
import semmle.code.java.dataflow.FlowSources
import DataFlow
import semmle.code.java.security.LdapInjection
/**
* A taint-tracking configuration for unvalidated user input that is used to construct LDAP queries.
*/
class LdapInjectionFlowConfig extends TaintTracking::Configuration {
LdapInjectionFlowConfig() { this = "LdapInjectionFlowConfig" }
module LdapInjectionFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof LdapInjectionSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof LdapInjectionSink }
predicate isBarrier(DataFlow::Node node) { node instanceof LdapInjectionSanitizer }
override predicate isSanitizer(DataFlow::Node node) { node instanceof LdapInjectionSanitizer }
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
any(LdapInjectionAdditionalTaintStep a).step(pred, succ)
}
}
module LdapInjectionFlow = TaintTracking::Make<LdapInjectionFlowConfig>;

View File

@@ -13,7 +13,6 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
private import semmle.code.java.dataflow.ExternalFlow
/**
@@ -56,14 +55,16 @@ class SetMessageInterpolatorCall extends MethodAccess {
* Taint tracking BeanValidationConfiguration describing the flow of data from user input
* to the argument of a method that builds constraint error messages.
*/
class BeanValidationConfig extends TaintTracking::Configuration {
BeanValidationConfig() { this = "BeanValidationConfig" }
module BeanValidationConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink }
predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink }
}
module BeanValidationFlow = TaintTracking::Make<BeanValidationConfig>;
import BeanValidationFlow::PathGraph
/**
* A bean validation sink, such as method `buildConstraintViolationWithTemplate`
* declared on a subtype of `javax.validation.ConstraintValidatorContext`.
@@ -72,13 +73,13 @@ private class BeanValidationSink extends DataFlow::Node {
BeanValidationSink() { sinkNode(this, "bean-validation") }
}
from BeanValidationConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
from BeanValidationFlow::PathNode source, BeanValidationFlow::PathNode sink
where
(
not exists(SetMessageInterpolatorCall c)
or
exists(SetMessageInterpolatorCall c | not c.isSafe())
) and
cfg.hasFlowPath(source, sink)
BeanValidationFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Custom constraint error message contains an unsanitized $@.",
source, "user-provided value"

View File

@@ -13,25 +13,29 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.StringFormat
import DataFlow::PathGraph
class ExternallyControlledFormatStringConfig extends TaintTracking::Configuration {
ExternallyControlledFormatStringConfig() { this = "ExternallyControlledFormatStringConfig" }
module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(StringFormat formatCall).getFormatArgument()
}
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof NumericType or node.getType() instanceof BooleanType
}
}
module ExternallyControlledFormatStringFlow =
TaintTracking::Make<ExternallyControlledFormatStringConfig>;
import ExternallyControlledFormatStringFlow::PathGraph
from
DataFlow::PathNode source, DataFlow::PathNode sink, StringFormat formatCall,
ExternallyControlledFormatStringConfig conf
where conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument()
ExternallyControlledFormatStringFlow::PathNode source,
ExternallyControlledFormatStringFlow::PathNode sink, StringFormat formatCall
where
ExternallyControlledFormatStringFlow::hasFlowPath(source, sink) and
sink.getNode().asExpr() = formatCall.getFormatArgument()
select formatCall.getFormatArgument(), source, sink, "Format string depends on a $@.",
source.getNode(), "user-provided value"

View File

@@ -13,23 +13,25 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.StringFormat
import DataFlow::PathGraph
class ExternallyControlledFormatStringLocalConfig extends TaintTracking::Configuration {
ExternallyControlledFormatStringLocalConfig() {
this = "ExternallyControlledFormatStringLocalConfig"
}
module ExternallyControlledFormatStringLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(StringFormat formatCall).getFormatArgument()
}
}
module ExternallyControlledFormatStringLocalFlow =
TaintTracking::Make<ExternallyControlledFormatStringLocalConfig>;
import ExternallyControlledFormatStringLocalFlow::PathGraph
from
DataFlow::PathNode source, DataFlow::PathNode sink, StringFormat formatCall,
ExternallyControlledFormatStringLocalConfig conf
where conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument()
ExternallyControlledFormatStringLocalFlow::PathNode source,
ExternallyControlledFormatStringLocalFlow::PathNode sink, StringFormat formatCall
where
ExternallyControlledFormatStringLocalFlow::hasFlowPath(source, sink) and
sink.getNode().asExpr() = formatCall.getFormatArgument()
select formatCall.getFormatArgument(), source, sink, "Format string depends on a $@.",
source.getNode(), "user-provided value"

View File

@@ -15,35 +15,41 @@
import java
import semmle.code.java.dataflow.FlowSources
import ArithmeticCommon
import DataFlow::PathGraph
class ArithmeticTaintedLocalOverflowConfig extends TaintTracking::Configuration {
ArithmeticTaintedLocalOverflowConfig() { this = "ArithmeticTaintedLocalOverflowConfig" }
module ArithmeticTaintedLocalOverflowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
override predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
override predicate isSanitizer(DataFlow::Node n) { overflowBarrier(n) }
predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
}
class ArithmeticTaintedLocalUnderflowConfig extends TaintTracking::Configuration {
ArithmeticTaintedLocalUnderflowConfig() { this = "ArithmeticTaintedLocalUnderflowConfig" }
module ArithmeticTaintedLocalOverflowFlow =
TaintTracking::Make<ArithmeticTaintedLocalOverflowConfig>;
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
module ArithmeticTaintedLocalUnderflowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
override predicate isSanitizer(DataFlow::Node n) { underflowBarrier(n) }
predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, string effect
module ArithmeticTaintedLocalUnderflowFlow =
TaintTracking::Make<ArithmeticTaintedLocalUnderflowConfig>;
module Flow =
DataFlow::MergePathGraph<ArithmeticTaintedLocalOverflowFlow::PathNode, ArithmeticTaintedLocalUnderflowFlow::PathNode, ArithmeticTaintedLocalOverflowFlow::PathGraph, ArithmeticTaintedLocalUnderflowFlow::PathGraph>;
import Flow::PathGraph
from Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect
where
any(ArithmeticTaintedLocalOverflowConfig c).hasFlowPath(source, sink) and
ArithmeticTaintedLocalOverflowFlow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and
overflowSink(exp, sink.getNode().asExpr()) and
effect = "overflow"
or
any(ArithmeticTaintedLocalUnderflowConfig c).hasFlowPath(source, sink) and
ArithmeticTaintedLocalUnderflowFlow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and
underflowSink(exp, sink.getNode().asExpr()) and
effect = "underflow"
select exp, source, sink,

View File

@@ -17,7 +17,6 @@ import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.RandomQuery
import semmle.code.java.security.SecurityTests
import ArithmeticCommon
import DataFlow::PathGraph
class TaintSource extends DataFlow::ExprNode {
TaintSource() {
@@ -25,33 +24,40 @@ class TaintSource extends DataFlow::ExprNode {
}
}
class ArithmeticUncontrolledOverflowConfig extends TaintTracking::Configuration {
ArithmeticUncontrolledOverflowConfig() { this = "ArithmeticUncontrolledOverflowConfig" }
module ArithmeticUncontrolledOverflowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof TaintSource }
override predicate isSource(DataFlow::Node source) { source instanceof TaintSource }
predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
override predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
override predicate isSanitizer(DataFlow::Node n) { overflowBarrier(n) }
predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
}
class ArithmeticUncontrolledUnderflowConfig extends TaintTracking::Configuration {
ArithmeticUncontrolledUnderflowConfig() { this = "ArithmeticUncontrolledUnderflowConfig" }
module ArithmeticUncontrolledOverflowFlow =
TaintTracking::Make<ArithmeticUncontrolledOverflowConfig>;
override predicate isSource(DataFlow::Node source) { source instanceof TaintSource }
module ArithmeticUncontrolledUnderflowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof TaintSource }
override predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
override predicate isSanitizer(DataFlow::Node n) { underflowBarrier(n) }
predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, string effect
module ArithmeticUncontrolledUnderflowFlow =
TaintTracking::Make<ArithmeticUncontrolledUnderflowConfig>;
module Flow =
DataFlow::MergePathGraph<ArithmeticUncontrolledOverflowFlow::PathNode, ArithmeticUncontrolledUnderflowFlow::PathNode, ArithmeticUncontrolledOverflowFlow::PathGraph, ArithmeticUncontrolledUnderflowFlow::PathGraph>;
import Flow::PathGraph
from Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect
where
any(ArithmeticUncontrolledOverflowConfig c).hasFlowPath(source, sink) and
ArithmeticUncontrolledOverflowFlow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and
overflowSink(exp, sink.getNode().asExpr()) and
effect = "overflow"
or
any(ArithmeticUncontrolledUnderflowConfig c).hasFlowPath(source, sink) and
ArithmeticUncontrolledUnderflowFlow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and
underflowSink(exp, sink.getNode().asExpr()) and
effect = "underflow"
select exp, source, sink,

View File

@@ -16,7 +16,6 @@
import java
import semmle.code.java.dataflow.DataFlow
import ArithmeticCommon
import DataFlow::PathGraph
abstract class ExtremeValueField extends Field {
ExtremeValueField() { this.getType() instanceof IntegralType }
@@ -34,43 +33,48 @@ class ExtremeSource extends VarAccess {
ExtremeSource() { this.getVariable() instanceof ExtremeValueField }
}
class MaxValueFlowConfig extends DataFlow::Configuration {
MaxValueFlowConfig() { this = "MaxValueFlowConfig" }
override predicate isSource(DataFlow::Node source) {
private module MaxValueFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(ExtremeSource).getVariable() instanceof MaxValueField
}
override predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
override predicate isBarrierIn(DataFlow::Node n) { this.isSource(n) }
predicate isBarrierIn(DataFlow::Node n) { isSource(n) }
override predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
}
class MinValueFlowConfig extends DataFlow::Configuration {
MinValueFlowConfig() { this = "MinValueFlowConfig" }
module MaxValueFlow = DataFlow::Make<MaxValueFlowConfig>;
override predicate isSource(DataFlow::Node source) {
private module MinValueFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(ExtremeSource).getVariable() instanceof MinValueField
}
override predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
override predicate isBarrierIn(DataFlow::Node n) { this.isSource(n) }
predicate isBarrierIn(DataFlow::Node n) { isSource(n) }
override predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
}
module MinValueFlow = DataFlow::Make<MinValueFlowConfig>;
module Flow =
DataFlow::MergePathGraph<MaxValueFlow::PathNode, MinValueFlow::PathNode, MaxValueFlow::PathGraph, MinValueFlow::PathGraph>;
import Flow::PathGraph
predicate query(
DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, string effect, Type srctyp
Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect, Type srctyp
) {
(
any(MaxValueFlowConfig c).hasFlowPath(source, sink) and
MaxValueFlow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and
overflowSink(exp, sink.getNode().asExpr()) and
effect = "overflow"
or
any(MinValueFlowConfig c).hasFlowPath(source, sink) and
MinValueFlow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and
underflowSink(exp, sink.getNode().asExpr()) and
effect = "underflow"
) and
@@ -78,7 +82,7 @@ predicate query(
}
from
DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, Variable v, ExtremeSource s,
Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, Variable v, ExtremeSource s,
string effect, Type srctyp
where
query(source, sink, exp, effect, srctyp) and

View File

@@ -61,10 +61,16 @@ class WebSettingsDisallowContentAccessSink extends DataFlow::Node {
}
}
class WebViewDisallowContentAccessConfiguration extends TaintTracking::Configuration {
WebViewDisallowContentAccessConfiguration() { this = "WebViewDisallowContentAccessConfiguration" }
private newtype WebViewOrSettings =
IsWebView() or
IsSettings()
override predicate isSource(DataFlow::Node node) { node instanceof WebViewSource }
module WebViewDisallowContentAccessConfig implements DataFlow::StateConfigSig {
class FlowState = WebViewOrSettings;
predicate isSource(DataFlow::Node node, FlowState state) {
node instanceof WebViewSource and state instanceof IsWebView
}
/**
* Holds if the step from `node1` to `node2` is a dataflow step that gets the `WebSettings` object
@@ -73,12 +79,11 @@ class WebViewDisallowContentAccessConfiguration extends TaintTracking::Configura
* This step is only valid when `state1` is empty and `state2` indicates that the `WebSettings` object
* has been accessed.
*/
override predicate isAdditionalTaintStep(
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
DataFlow::FlowState state2
predicate isAdditionalFlowStep(
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
) {
state1 instanceof DataFlow::FlowStateEmpty and
state2 = "WebSettings" and
state1 instanceof IsWebView and
state2 instanceof IsSettings and
// settings = webView.getSettings()
// ^node2 = ^node1
exists(MethodAccess ma |
@@ -88,12 +93,17 @@ class WebViewDisallowContentAccessConfiguration extends TaintTracking::Configura
)
}
override predicate isSink(DataFlow::Node node, DataFlow::FlowState state) {
state = "WebSettings" and
predicate isSink(DataFlow::Node node, FlowState state) {
state instanceof IsSettings and
node instanceof WebSettingsDisallowContentAccessSink
}
predicate isBarrier(DataFlow::Node node, FlowState state) { none() }
}
module WebViewDisallowContentAccessFlow =
TaintTracking::MakeWithState<WebViewDisallowContentAccessConfig>;
from Expr e
where
// explicit: setAllowContentAccess(true)
@@ -106,7 +116,7 @@ where
// implicit: no setAllowContentAccess(false)
exists(WebViewSource source |
source.asExpr() = e and
not any(WebViewDisallowContentAccessConfiguration cfg).hasFlow(source, _)
not WebViewDisallowContentAccessFlow::hasFlow(source, _)
)
select e,
"Sensitive information may be exposed via a malicious link due to access to content:// links being allowed in this WebView."

View File

@@ -16,7 +16,6 @@ import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.Encryption
import semmle.code.java.security.SecurityFlag
import DataFlow::PathGraph
private import semmle.code.java.dataflow.ExternalFlow
/**
@@ -45,16 +44,14 @@ class TrustAllHostnameVerifier extends RefType {
/**
* A configuration to model the flow of a `TrustAllHostnameVerifier` to a `set(Default)HostnameVerifier` call.
*/
class TrustAllHostnameVerifierConfiguration extends DataFlow::Configuration {
TrustAllHostnameVerifierConfiguration() { this = "TrustAllHostnameVerifierConfiguration" }
override predicate isSource(DataFlow::Node source) {
module TrustAllHostnameVerifierConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof TrustAllHostnameVerifier
}
override predicate isSink(DataFlow::Node sink) { sink instanceof HostnameVerifierSink }
predicate isSink(DataFlow::Node sink) { sink instanceof HostnameVerifierSink }
override predicate isBarrier(DataFlow::Node barrier) {
predicate isBarrier(DataFlow::Node barrier) {
// ignore nodes that are in functions that intentionally disable hostname verification
barrier
.getEnclosingCallable()
@@ -80,6 +77,10 @@ class TrustAllHostnameVerifierConfiguration extends DataFlow::Configuration {
}
}
module TrustAllHostnameVerifierFlow = DataFlow::Make<TrustAllHostnameVerifierConfig>;
import TrustAllHostnameVerifierFlow::PathGraph
/**
* A sink that sets the `HostnameVerifier` on `HttpsURLConnection`.
*/
@@ -114,10 +115,10 @@ private predicate isNodeGuardedByFlag(DataFlow::Node node) {
}
from
DataFlow::PathNode source, DataFlow::PathNode sink, TrustAllHostnameVerifierConfiguration cfg,
TrustAllHostnameVerifierFlow::PathNode source, TrustAllHostnameVerifierFlow::PathNode sink,
RefType verifier
where
cfg.hasFlowPath(source, sink) and
TrustAllHostnameVerifierFlow::hasFlowPath(source, sink) and
not isNodeGuardedByFlag(sink.getNode()) and
verifier = source.getNode().asExpr().(ClassInstanceExpr).getConstructedType()
select sink, source, sink,

View File

@@ -14,17 +14,18 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.UrlRedirect
import DataFlow::PathGraph
class UrlRedirectConfig extends TaintTracking::Configuration {
UrlRedirectConfig() { this = "UrlRedirectConfig" }
module UrlRedirectConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink }
predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, UrlRedirectConfig conf
where conf.hasFlowPath(source, sink)
module UrlRedirectFlow = TaintTracking::Make<UrlRedirectConfig>;
import UrlRedirectFlow::PathGraph
from UrlRedirectFlow::PathNode source, UrlRedirectFlow::PathNode sink
where UrlRedirectFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -14,17 +14,18 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.UrlRedirect
import DataFlow::PathGraph
class UrlRedirectLocalConfig extends TaintTracking::Configuration {
UrlRedirectLocalConfig() { this = "UrlRedirectLocalConfig" }
module UrlRedirectLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink }
predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, UrlRedirectLocalConfig conf
where conf.hasFlowPath(source, sink)
module UrlRedirectLocalFlow = TaintTracking::Make<UrlRedirectLocalConfig>;
import UrlRedirectLocalFlow::PathGraph
from UrlRedirectLocalFlow::PathNode source, UrlRedirectLocalFlow::PathNode sink
where UrlRedirectLocalFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -16,10 +16,10 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.security.XxeRemoteQuery
import DataFlow::PathGraph
import XxeFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, XxeConfig conf
where conf.hasFlowPath(source, sink)
from XxeFlow::PathNode source, XxeFlow::PathNode sink
where XxeFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"XML parsing depends on a $@ without guarding against external entity expansion.",
source.getNode(), "user-provided value"

View File

@@ -16,10 +16,10 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.security.XxeLocalQuery
import DataFlow::PathGraph
import XxeLocalFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, XxeLocalConfig conf
where conf.hasFlowPath(source, sink)
from XxeLocalFlow::PathNode source, XxeLocalFlow::PathNode sink
where XxeLocalFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"XML parsing depends on a $@ without guarding against external entity expansion.",
source.getNode(), "user-provided value"

View File

@@ -15,17 +15,18 @@ import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.XPath
import DataFlow::PathGraph
class XPathInjectionConfiguration extends TaintTracking::Configuration {
XPathInjectionConfiguration() { this = "XPathInjection" }
module XPathInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof XPathInjectionSink }
predicate isSink(DataFlow::Node sink) { sink instanceof XPathInjectionSink }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, XPathInjectionConfiguration c
where c.hasFlowPath(source, sink)
module XPathInjectionFlow = TaintTracking::Make<XPathInjectionConfig>;
import XPathInjectionFlow::PathGraph
from XPathInjectionFlow::PathNode source, XPathInjectionFlow::PathNode sink
where XPathInjectionFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "XPath expression depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -14,7 +14,7 @@
import java
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
import semmle.code.java.dataflow.TaintTracking
class TypeShiroSubject extends RefType {
TypeShiroSubject() { this.getQualifiedName() = "org.apache.shiro.subject.Subject" }
@@ -52,19 +52,22 @@ class WCPermissionConstruction extends ClassInstanceExpr, PermissionsConstructio
override Expr getInput() { result = this.getArgument(0) }
}
class TaintedPermissionsCheckFlowConfig extends TaintTracking::Configuration {
TaintedPermissionsCheckFlowConfig() { this = "TaintedPermissionsCheckFlowConfig" }
module TaintedPermissionsCheckFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof UserInput }
override predicate isSource(DataFlow::Node source) { source instanceof UserInput }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(PermissionsConstruction p).getInput()
}
}
module TaintedPermissionsCheckFlow = TaintTracking::Make<TaintedPermissionsCheckFlowConfig>;
import TaintedPermissionsCheckFlow::PathGraph
from
DataFlow::PathNode source, DataFlow::PathNode sink, PermissionsConstruction p,
TaintedPermissionsCheckFlowConfig conf
where sink.getNode().asExpr() = p.getInput() and conf.hasFlowPath(source, sink)
TaintedPermissionsCheckFlow::PathNode source, TaintedPermissionsCheckFlow::PathNode sink,
PermissionsConstruction p
where
sink.getNode().asExpr() = p.getInput() and TaintedPermissionsCheckFlow::hasFlowPath(source, sink)
select p, source, sink, "Permissions check depends on a $@.", source.getNode(),
"user-controlled value"