Refactor Security.CWE.CWE-190 Arithmetic queries

This commit is contained in:
Ed Minnix
2023-03-15 14:23:37 -04:00
parent 4a202b430f
commit 7bd7ecd9e6
3 changed files with 64 additions and 48 deletions

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" }
private 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 }
private 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" }
private 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 }
private 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