use tainted-object to precisely model that plain object are fine, but their properties are not

This commit is contained in:
erik-krogh
2023-02-15 13:23:01 +01:00
parent 09794fa836
commit 51ddb55d7b
4 changed files with 133 additions and 17 deletions

View File

@@ -182,16 +182,17 @@ module UnsafeHtmlConstruction {
}
/** A test for the value of `typeof x`, restricting the potential types of `x`. */
class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
class TypeTestGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode {
override EqualityTest astNode;
Expr operand;
boolean polarity;
TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) }
override predicate sanitizes(boolean outcome, Expr e) {
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) {
polarity = outcome and
e = operand
e = operand and
lbl.isTaint()
}
}
}

View File

@@ -7,6 +7,7 @@ import javascript
private import semmle.javascript.security.dataflow.DomBasedXssCustomizations::DomBasedXss as DomBasedXss
private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin as UnsafeJQueryPlugin
import UnsafeHtmlConstructionCustomizations::UnsafeHtmlConstruction
import semmle.javascript.security.TaintedObject
/**
* A taint-tracking configuration for reasoning about unsafe HTML constructed from library input vulnerabilities.
@@ -14,9 +15,15 @@ import UnsafeHtmlConstructionCustomizations::UnsafeHtmlConstruction
class Configration extends TaintTracking::Configuration {
Configration() { this = "UnsafeHtmlConstruction" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source instanceof Source and
label = [TaintedObject::label(), DataFlow::FlowLabel::taint(), DataFlow::FlowLabel::data()]
}
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink instanceof Sink and
label = DataFlow::FlowLabel::taint()
}
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node)
@@ -36,8 +43,19 @@ class Configration extends TaintTracking::Configuration {
DataFlow::hasPathWithoutUnmatchedReturn(source, sink)
}
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
DataFlow::localFieldStep(pred, succ)
override predicate isAdditionalFlowStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
) {
DataFlow::localFieldStep(pred, succ) and
inlbl.isTaint() and
outlbl.isTaint()
or
TaintedObject::step(pred, succ, inlbl, outlbl)
or
// property read from a tainted object is considered tainted
succ.(DataFlow::PropRead).getBase() = pred and
inlbl = TaintedObject::label() and
outlbl = DataFlow::FlowLabel::taint()
}
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {