use strings in isTypeofGard

This commit is contained in:
Erik Krogh Kristensen
2020-12-22 13:26:49 +01:00
parent df95562f8f
commit f7f88689c4
9 changed files with 27 additions and 30 deletions

View File

@@ -396,18 +396,18 @@ class InstanceOfGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::Value
class TypeofGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode {
override EqualityTest astNode;
Expr operand;
InferredType type;
TypeofTag tag;
TypeofGuard() { TaintTracking::isTypeofGuard(astNode, operand, type) }
TypeofGuard() { TaintTracking::isTypeofGuard(astNode, operand, tag) }
override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) {
e = operand and
outcome = astNode.getPolarity() and
(
type = TTObject() and
tag = "object" and
label = "constructor"
or
type = TTFunction() and
tag = "function" and
label = "__proto__"
)
or
@@ -416,10 +416,10 @@ class TypeofGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode
(
// If something is not an object, sanitize object, as both must end
// in non-function prototype object.
type = TTObject() and
tag = "object" and
label instanceof UnsafePropLabel
or
type = TTFunction() and
tag = "function" and
label = "constructor"
)
}

View File

@@ -326,15 +326,15 @@ module DefensiveExpressionTest {
*/
private class TypeofTest extends EqualityTest {
Expr operand;
InferredType type;
TypeofTag tag;
TypeofTest() { TaintTracking::isTypeofGuard(this, operand, type) }
TypeofTest() { TaintTracking::isTypeofGuard(this, operand, tag) }
boolean getTheTestResult() {
exists(boolean testResult |
testResult = true and operand.analyze().getTheType() = type
testResult = true and operand.analyze().getTheType().getTypeofTag() = tag
or
testResult = false and not operand.analyze().getAType() = type
testResult = false and not operand.analyze().getAType().getTypeofTag() = tag
|
if getPolarity() = true then result = testResult else result = testResult.booleanNot()
)
@@ -348,7 +348,7 @@ module DefensiveExpressionTest {
/**
* Gets the `typeof` tag that is tested.
*/
TypeofTag getTag() { result = type.getTypeofTag() }
TypeofTag getTag() { result = tag }
}
/**

View File

@@ -899,7 +899,7 @@ module TaintTracking {
Expr x;
override EqualityTest astNode;
TypeOfUndefinedSanitizer() { isTypeofGuard(astNode, x, TTUndefined()) }
TypeOfUndefinedSanitizer() { isTypeofGuard(astNode, x, "undefined") }
override predicate sanitizes(boolean outcome, Expr e) {
outcome = astNode.getPolarity() and
@@ -910,13 +910,13 @@ module TaintTracking {
}
/**
* Holds if `test` is a guard that checks if `operand` is typeof `type`.
* Holds if `test` is a guard that checks if `operand` is typeof `tag`.
*
* See `TypeOfUndefinedSanitizer` for example usage.
*/
predicate isTypeofGuard(EqualityTest test, Expr operand, InferredType type) {
predicate isTypeofGuard(EqualityTest test, Expr operand, TypeofTag tag) {
exists(Expr str, TypeofExpr typeof | test.hasOperands(str, typeof) |
str.mayHaveStringValue(type.getTypeofTag()) and
str.mayHaveStringValue(tag) and
typeof.getOperand() = operand
)
}

View File

@@ -103,13 +103,13 @@ module TaintedObject {
boolean polarity;
TypeTestGuard() {
exists(InferredType type | TaintTracking::isTypeofGuard(astNode, operand, type) |
exists(TypeofTag tag | TaintTracking::isTypeofGuard(astNode, operand, tag) |
// typeof x === "object" sanitizes `x` when it evaluates to false
type = TTObject() and
tag = "object" and
polarity = astNode.getPolarity().booleanNot()
or
// typeof x === "string" sanitizes `x` when it evaluates to true
type != TTObject() and
tag != "object" and
polarity = astNode.getPolarity()
)
}

View File

@@ -168,10 +168,10 @@ module PrototypePollutingAssignment {
boolean polarity;
TypeofCheck() {
exists(InferredType type | TaintTracking::isTypeofGuard(astNode, operand, type) |
type = TTObject() and polarity = astNode.getPolarity().booleanNot()
exists(TypeofTag value | TaintTracking::isTypeofGuard(astNode, operand, value) |
value = "object" and polarity = astNode.getPolarity().booleanNot()
or
type != TTObject() and polarity = astNode.getPolarity()
value != "object" and polarity = astNode.getPolarity()
)
}

View File

@@ -134,7 +134,7 @@ module UnsafeJQueryPlugin {
SyntacticConstants::isUndefined(undef)
)
or
TaintTracking::isTypeofGuard(test, read.asExpr(), TTUndefined())
TaintTracking::isTypeofGuard(test, read.asExpr(), "undefined")
)
or
polarity = true and

View File

@@ -199,10 +199,7 @@ module UnsafeShellCommandConstruction {
Expr x;
override EqualityTest astNode;
TypeOfSanitizer() {
TaintTracking::isTypeofGuard(astNode, x,
any(InferredType t | t = TTNumber() or t = TTBoolean()))
}
TypeOfSanitizer() { TaintTracking::isTypeofGuard(astNode, x, ["number", "boolean"]) }
override predicate sanitizes(boolean outcome, Expr e) {
outcome = astNode.getPolarity() and

View File

@@ -100,7 +100,7 @@ module UnvalidatedDynamicMethodCall {
override EqualityTest astNode;
Expr operand;
FunctionCheck() { TaintTracking::isTypeofGuard(astNode, operand, TTFunction()) }
FunctionCheck() { TaintTracking::isTypeofGuard(astNode, operand, "function") }
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
outcome = astNode.getPolarity() and

View File

@@ -108,13 +108,13 @@ module XssThroughDom {
boolean polarity;
TypeTestGuard() {
exists(InferredType type | TaintTracking::isTypeofGuard(astNode, operand, type) |
exists(TypeofTag tag | TaintTracking::isTypeofGuard(astNode, operand, tag) |
// typeof x === "string" sanitizes `x` when it evaluates to false
type = TTString() and
tag = "string" and
polarity = astNode.getPolarity().booleanNot()
or
// typeof x === "object" sanitizes `x` when it evaluates to true
type != TTString() and
tag != "string" and
polarity = astNode.getPolarity()
)
}