@@ -173,6 +173,44 @@ module TaintTracking {
173173 override DataFlow:: FlowLabel getDefaultSourceLabel ( ) { result .isTaint ( ) }
174174 }
175175
176+ /**
177+ * A barrier guard that applies to all taint-tracking configurations.
178+ *
179+ * Note: For performance reasons, all subclasses of this class should be part
180+ * of the standard library. To define a query-specific barrier guard, instead override
181+ * `isBarrier` and use the `DataFlow::MakeBarrierGuard` module. For example:
182+ * ```codeql
183+ * module MyConfig implements DataFlow::ConfigSig {
184+ * predicate isBarrier(DataFlow::Node node) {
185+ * node = DataFlow::MakeBarrierGuard<MyGuard>
186+ * }
187+ * }
188+ * class MyGuard extends DataFlow::Node {
189+ * MyGuard() { ... }
190+ * predicate blocksExpr(boolean outcome, Expr e) { ... }
191+ * }
192+ */
193+ abstract class AdditionalBarrierGuard extends DataFlow:: Node {
194+ /**
195+ * Holds if this node blocks expression `e`, provided it evaluates to `outcome`.
196+ */
197+ abstract predicate blocksExpr ( boolean outcome , Expr e ) ;
198+ }
199+
200+ /**
201+ * Internal barrier guard class that populates both the new `AdditionalBarrierGuard` class
202+ * and the legacy `AdditionalSanitizerGuardNode` class.
203+ *
204+ * It exposes the member predicates of `AdditionalSanitizerGuardNode` for backwards compatibility.
205+ */
206+ abstract private class LegacyAdditionalBarrierGuard extends AdditionalBarrierGuard ,
207+ AdditionalSanitizerGuardNode
208+ {
209+ override predicate sanitizes ( boolean outcome , Expr e ) { this .blocksExpr ( outcome , e ) }
210+
211+ deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
212+ }
213+
176214 /**
177215 * A `SanitizerGuardNode` that controls which taint tracking
178216 * configurations it is used in.
@@ -779,7 +817,7 @@ module TaintTracking {
779817 * A conditional checking a tainted string against a regular expression, which is
780818 * considered to be a sanitizer for all configurations.
781819 */
782- class SanitizingRegExpTest extends AdditionalSanitizerGuardNode , DataFlow:: ValueNode {
820+ class SanitizingRegExpTest extends LegacyAdditionalBarrierGuard , DataFlow:: ValueNode {
783821 Expr expr ;
784822 boolean sanitizedOutcome ;
785823
@@ -812,12 +850,10 @@ module TaintTracking {
812850
813851 private boolean getSanitizedOutcome ( ) { result = sanitizedOutcome }
814852
815- override predicate sanitizes ( boolean outcome , Expr e ) {
853+ override predicate blocksExpr ( boolean outcome , Expr e ) {
816854 outcome = sanitizedOutcome and
817855 e = expr
818856 }
819-
820- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
821857 }
822858
823859 /**
@@ -827,23 +863,21 @@ module TaintTracking {
827863 *
828864 * Note that the `includes` method is covered by `MembershipTestSanitizer`.
829865 */
830- class WhitelistContainmentCallSanitizer extends AdditionalSanitizerGuardNode ,
866+ class WhitelistContainmentCallSanitizer extends LegacyAdditionalBarrierGuard ,
831867 DataFlow:: MethodCallNode
832868 {
833869 WhitelistContainmentCallSanitizer ( ) {
834870 this .getMethodName ( ) = [ "contains" , "has" , "hasOwnProperty" , "hasOwn" ]
835871 }
836872
837- override predicate sanitizes ( boolean outcome , Expr e ) {
873+ override predicate blocksExpr ( boolean outcome , Expr e ) {
838874 exists ( int propertyIndex |
839875 if this .getMethodName ( ) = "hasOwn" then propertyIndex = 1 else propertyIndex = 0
840876 |
841877 outcome = true and
842878 e = this .getArgument ( propertyIndex ) .asExpr ( )
843879 )
844880 }
845-
846- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
847881 }
848882
849883 /**
@@ -876,19 +910,17 @@ module TaintTracking {
876910 module AdHocWhitelistCheckSanitizer = DataFlow:: MakeBarrierGuard< AdHocWhitelistCheckSanitizer > ;
877911
878912 /** A check of the form `if(x in o)`, which sanitizes `x` in its "then" branch. */
879- class InSanitizer extends AdditionalSanitizerGuardNode , DataFlow:: ValueNode {
913+ class InSanitizer extends LegacyAdditionalBarrierGuard , DataFlow:: ValueNode {
880914 override InExpr astNode ;
881915
882- override predicate sanitizes ( boolean outcome , Expr e ) {
916+ override predicate blocksExpr ( boolean outcome , Expr e ) {
883917 outcome = true and
884918 e = astNode .getLeftOperand ( )
885919 }
886-
887- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
888920 }
889921
890922 /** A check of the form `if(o[x] != undefined)`, which sanitizes `x` in its "then" branch. */
891- class UndefinedCheckSanitizer extends AdditionalSanitizerGuardNode , DataFlow:: ValueNode {
923+ class UndefinedCheckSanitizer extends LegacyAdditionalBarrierGuard , DataFlow:: ValueNode {
892924 Expr x ;
893925 override EqualityTest astNode ;
894926
@@ -904,27 +936,23 @@ module TaintTracking {
904936 )
905937 }
906938
907- override predicate sanitizes ( boolean outcome , Expr e ) {
939+ override predicate blocksExpr ( boolean outcome , Expr e ) {
908940 outcome = astNode .getPolarity ( ) .booleanNot ( ) and
909941 e = x
910942 }
911-
912- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
913943 }
914944
915945 /** A check of the form `type x === "undefined"`, which sanitized `x` in its "then" branch. */
916- class TypeOfUndefinedSanitizer extends AdditionalSanitizerGuardNode , DataFlow:: ValueNode {
946+ class TypeOfUndefinedSanitizer extends LegacyAdditionalBarrierGuard , DataFlow:: ValueNode {
917947 Expr x ;
918948 override EqualityTest astNode ;
919949
920950 TypeOfUndefinedSanitizer ( ) { isTypeofGuard ( astNode , x , "undefined" ) }
921951
922- override predicate sanitizes ( boolean outcome , Expr e ) {
952+ override predicate blocksExpr ( boolean outcome , Expr e ) {
923953 outcome = astNode .getPolarity ( ) and
924954 e = x
925955 }
926-
927- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
928956 }
929957
930958 /**
@@ -985,7 +1013,7 @@ module TaintTracking {
9851013 /**
9861014 * A test of form `x.length === "0"`, preventing `x` from being tainted.
9871015 */
988- class IsEmptyGuard extends AdditionalSanitizerGuardNode , DataFlow:: ValueNode {
1016+ class IsEmptyGuard extends LegacyAdditionalBarrierGuard , DataFlow:: ValueNode {
9891017 override EqualityTest astNode ;
9901018 boolean polarity ;
9911019 Expr operand ;
@@ -999,32 +1027,28 @@ module TaintTracking {
9991027 )
10001028 }
10011029
1002- override predicate sanitizes ( boolean outcome , Expr e ) { polarity = outcome and e = operand }
1003-
1004- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
1030+ override predicate blocksExpr ( boolean outcome , Expr e ) { polarity = outcome and e = operand }
10051031 }
10061032
10071033 /**
10081034 * A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch.
10091035 */
1010- class MembershipTestSanitizer extends AdditionalSanitizerGuardNode {
1036+ class MembershipTestSanitizer extends LegacyAdditionalBarrierGuard {
10111037 MembershipCandidate candidate ;
10121038
10131039 MembershipTestSanitizer ( ) { this = candidate .getTest ( ) }
10141040
1015- override predicate sanitizes ( boolean outcome , Expr e ) {
1041+ override predicate blocksExpr ( boolean outcome , Expr e ) {
10161042 candidate = e .flow ( ) and candidate .getTestPolarity ( ) = outcome
10171043 }
1018-
1019- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
10201044 }
10211045
10221046 /**
10231047 * A check of form `x.indexOf(y) > 0` or similar, which sanitizes `y` in the "then" branch.
10241048 *
10251049 * The more typical case of `x.indexOf(y) >= 0` is covered by `MembershipTestSanitizer`.
10261050 */
1027- class PositiveIndexOfSanitizer extends AdditionalSanitizerGuardNode , DataFlow:: ValueNode {
1051+ class PositiveIndexOfSanitizer extends LegacyAdditionalBarrierGuard , DataFlow:: ValueNode {
10281052 MethodCallExpr indexOf ;
10291053 override RelationalComparison astNode ;
10301054
@@ -1037,19 +1061,17 @@ module TaintTracking {
10371061 )
10381062 }
10391063
1040- override predicate sanitizes ( boolean outcome , Expr e ) {
1064+ override predicate blocksExpr ( boolean outcome , Expr e ) {
10411065 outcome = true and
10421066 e = indexOf .getArgument ( 0 )
10431067 }
1044-
1045- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
10461068 }
10471069
10481070 /**
10491071 * An equality test on `e.origin` or `e.source` where `e` is a `postMessage` event object,
10501072 * considered as a sanitizer for `e`.
10511073 */
1052- private class PostMessageEventSanitizer extends AdditionalSanitizerGuardNode {
1074+ private class PostMessageEventSanitizer extends LegacyAdditionalBarrierGuard {
10531075 VarAccess event ;
10541076 boolean polarity ;
10551077
@@ -1066,12 +1088,10 @@ module TaintTracking {
10661088 )
10671089 }
10681090
1069- override predicate sanitizes ( boolean outcome , Expr e ) {
1091+ override predicate blocksExpr ( boolean outcome , Expr e ) {
10701092 outcome = polarity and
10711093 e = event
10721094 }
1073-
1074- deprecated override predicate appliesTo ( Configuration cfg ) { any ( ) }
10751095 }
10761096
10771097 import internal.sharedlib.TaintTracking
0 commit comments