| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,4 @@ | |||
| 1 | + --- | ||
| 2 | + category: minorAnalysis | ||
| 3 | + --- | ||
| 4 | + * Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ private module Frameworks { | |||
| 28 | 28 | private import semmle.code.java.frameworks.ThreadLocal | |
| 29 | 29 | private import semmle.code.java.frameworks.ratpack.RatpackExec | |
| 30 | 30 | private import semmle.code.java.frameworks.stapler.Stapler | |
| 31 | + private import semmle.code.java.security.ListOfConstantsSanitizer | ||
| 31 | 32 | } | |
| 32 | 33 | ||
| 33 | 34 | /** | |
@@ -189,3 +190,8 @@ private class NumberTaintPreservingCallable extends TaintPreservingCallable { | |||
| 189 | 190 | * map-key and map-value content, so that e.g. a tainted `Map` is assumed to have tainted keys and values. | |
| 190 | 191 | */ | |
| 191 | 192 | abstract class TaintInheritingContent extends DataFlow::Content { } | |
| 193 | + | ||
| 194 | + /** | ||
| 195 | + * A sanitizer in all global taint flow configurations but not in local taint. | ||
| 196 | + */ | ||
| 197 | + abstract class DefaultTaintSanitizer extends DataFlow::Node { } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,46 +13,55 @@ private import semmle.code.java.dispatch.VirtualDispatch | |||
| 13 | 13 | private import semmle.code.java.dataflow.internal.BaseSSA | |
| 14 | 14 | private import semmle.code.java.controlflow.Guards | |
| 15 | 15 | private import codeql.typeflow.TypeFlow | |
| 16 | + private import codeql.typeflow.UniversalFlow as UniversalFlow | ||
| 16 | 17 | ||
| 17 | - private module Input implements TypeFlowInput<Location> { | ||
| 18 | - private newtype TTypeFlowNode = | ||
| 18 | + /** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */ | ||
| 19 | + private RefType boxIfNeeded(J::Type t) { | ||
| 20 | + t.(PrimitiveType).getBoxedType() = result or | ||
| 21 | + result = t | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + /** Provides the input types and predicates for instantiation of `UniversalFlow`. */ | ||
| 25 | + module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> { | ||
| 26 | + private newtype TFlowNode = | ||
| 19 | 27 | TField(Field f) { not f.getType() instanceof PrimitiveType } or | |
| 20 | 28 | TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or | |
| 21 | 29 | TExpr(Expr e) or | |
| 22 | 30 | TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType } | |
| 23 | 31 | ||
| 24 | - /** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */ | ||
| 25 | - private RefType boxIfNeeded(J::Type t) { | ||
| 26 | - t.(PrimitiveType).getBoxedType() = result or | ||
| 27 | - result = t | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | 32 | /** | |
| 31 | 33 | * A `Field`, `BaseSsaVariable`, `Expr`, or `Method`. | |
| 32 | 34 | */ | |
| 33 | - class TypeFlowNode extends TTypeFlowNode { | ||
| 35 | + class FlowNode extends TFlowNode { | ||
| 36 | + /** Gets a textual representation of this element. */ | ||
| 34 | 37 | string toString() { | |
| 35 | 38 | result = this.asField().toString() or | |
| 36 | 39 | result = this.asSsa().toString() or | |
| 37 | 40 | result = this.asExpr().toString() or | |
| 38 | 41 | result = this.asMethod().toString() | |
| 39 | 42 | } | |
| 40 | 43 | ||
| 44 | + /** Gets the source location for this element. */ | ||
| 41 | 45 | Location getLocation() { | |
| 42 | 46 | result = this.asField().getLocation() or | |
| 43 | 47 | result = this.asSsa().getLocation() or | |
| 44 | 48 | result = this.asExpr().getLocation() or | |
| 45 | 49 | result = this.asMethod().getLocation() | |
| 46 | 50 | } | |
| 47 | 51 | ||
| 52 | + /** Gets the field corresponding to this node, if any. */ | ||
| 48 | 53 | Field asField() { this = TField(result) } | |
| 49 | 54 | ||
| 55 | + /** Gets the SSA variable corresponding to this node, if any. */ | ||
| 50 | 56 | BaseSsaVariable asSsa() { this = TSsa(result) } | |
| 51 | 57 | ||
| 58 | + /** Gets the expression corresponding to this node, if any. */ | ||
| 52 | 59 | Expr asExpr() { this = TExpr(result) } | |
| 53 | 60 | ||
| 61 | + /** Gets the method corresponding to this node, if any. */ | ||
| 54 | 62 | Method asMethod() { this = TMethod(result) } | |
| 55 | 63 | ||
| 64 | + /** Gets the type of this node. */ | ||
| 56 | 65 | RefType getType() { | |
| 57 | 66 | result = this.asField().getType() or | |
| 58 | 67 | result = this.asSsa().getSourceVariable().getType() or | |
@@ -61,8 +70,6 @@ private module Input implements TypeFlowInput<Location> { | |||
| 61 | 70 | } | |
| 62 | 71 | } | |
| 63 | 72 | ||
| 64 | - class Type = RefType; | ||
| 65 | - | ||
| 66 | 73 | private SrcCallable viableCallable_v1(Call c) { | |
| 67 | 74 | result = viableImpl_v1(c) | |
| 68 | 75 | or | |
@@ -88,7 +95,7 @@ private module Input implements TypeFlowInput<Location> { | |||
| 88 | 95 | * | |
| 89 | 96 | * For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`. | |
| 90 | 97 | */ | |
| 91 | - predicate step(TypeFlowNode n1, TypeFlowNode n2) { | ||
| 98 | + predicate step(FlowNode n1, FlowNode n2) { | ||
| 92 | 99 | n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr() | |
| 93 | 100 | or | |
| 94 | 101 | exists(Field f, Expr e | | |
@@ -134,7 +141,7 @@ private module Input implements TypeFlowInput<Location> { | |||
| 134 | 141 | /** | |
| 135 | 142 | * Holds if `null` is the only value that flows to `n`. | |
| 136 | 143 | */ | |
| 137 | - predicate isNullValue(TypeFlowNode n) { | ||
| 144 | + predicate isNullValue(FlowNode n) { | ||
| 138 | 145 | n.asExpr() instanceof NullLiteral | |
| 139 | 146 | or | |
| 140 | 147 | exists(LocalVariableDeclExpr decl | | |
@@ -144,11 +151,21 @@ private module Input implements TypeFlowInput<Location> { | |||
| 144 | 151 | ) | |
| 145 | 152 | } | |
| 146 | 153 | ||
| 147 | - predicate isExcludedFromNullAnalysis(TypeFlowNode n) { | ||
| 154 | + predicate isExcludedFromNullAnalysis(FlowNode n) { | ||
| 148 | 155 | // Fields that are never assigned a non-null value are probably set by | |
| 149 | 156 | // reflection and are thus not always null. | |
| 150 | 157 | exists(n.asField()) | |
| 151 | 158 | } | |
| 159 | + } | ||
| 160 | + | ||
| 161 | + private module Input implements TypeFlowInput<Location> { | ||
| 162 | + import FlowStepsInput | ||
| 163 | + | ||
| 164 | + class TypeFlowNode = FlowNode; | ||
| 165 | + | ||
| 166 | + predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1; | ||
| 167 | + | ||
| 168 | + class Type = RefType; | ||
| 152 | 169 | ||
| 153 | 170 | predicate exactTypeBase(TypeFlowNode n, RefType t) { | |
| 154 | 171 | exists(ClassInstanceExpr e | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,6 +38,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable { | |||
| 38 | 38 | /** Gets the `Callable` in which this `BaseSsaSourceVariable` is defined. */ | |
| 39 | 39 | Callable getEnclosingCallable() { this = TLocalVar(result, _) } | |
| 40 | 40 | ||
| 41 | + /** Gets a textual representation of this element. */ | ||
| 41 | 42 | string toString() { | |
| 42 | 43 | exists(LocalScopeVariable v, Callable c | this = TLocalVar(c, v) | | |
| 43 | 44 | if c = v.getCallable() | |
@@ -46,6 +47,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable { | |||
| 46 | 47 | ) | |
| 47 | 48 | } | |
| 48 | 49 | ||
| 50 | + /** Gets the source location for this element. */ | ||
| 49 | 51 | Location getLocation() { | |
| 50 | 52 | exists(LocalScopeVariable v | this = TLocalVar(_, v) and result = v.getLocation()) | |
| 51 | 53 | } | |
@@ -482,8 +484,10 @@ class BaseSsaVariable extends TBaseSsaVariable { | |||
| 482 | 484 | this = TSsaEntryDef(_, result) | |
| 483 | 485 | } | |
| 484 | 486 | ||
| 487 | + /** Gets a textual representation of this element. */ | ||
| 485 | 488 | string toString() { none() } | |
| 486 | 489 | ||
| 490 | + /** Gets the source location for this element. */ | ||
| 487 | 491 | Location getLocation() { result = this.getCfgNode().getLocation() } | |
| 488 | 492 | ||
| 489 | 493 | /** Gets the `BasicBlock` in which this SSA variable is defined. */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -161,6 +161,7 @@ private module Cached { | |||
| 161 | 161 | */ | |
| 162 | 162 | cached | |
| 163 | 163 | predicate defaultTaintSanitizer(DataFlow::Node node) { | |
| 164 | + node instanceof DefaultTaintSanitizer or | ||
| 164 | 165 | // Ignore paths through test code. | |
| 165 | 166 | node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass or | |
| 166 | 167 | node.asExpr() instanceof ValidatedVariableAccess | |
| Back | FazBrowse Home | New Git URL |
0 commit comments