@@ -665,3 +665,83 @@ private predicate entrypointFieldStep(DataFlow::Node src, DataFlow::Node sink) {
665665 ) and
666666 src .getType ( ) .( RefType ) .getSourceDeclaration ( ) = entrypointType ( )
667667}
668+
669+ /**
670+ * A comparison against a list of compile-time constants, sanitizing taint by
671+ * restricting to a set of known values.
672+ */
673+ class ListOfConstantsComparisonSanitizerGuard extends TaintTracking:: DefaultTaintSanitizer {
674+ ListOfConstantsComparisonSanitizerGuard ( ) {
675+ this = DataFlow:: BarrierGuard< listOfConstantsComparisonSanitizerGuard / 3 > :: getABarrierNode ( )
676+ }
677+ }
678+
679+ private predicate listOfConstantsComparisonSanitizerGuard ( Guard g , Expr e , boolean outcome ) {
680+ exists ( ListOfConstantsComparison locc |
681+ g = locc and
682+ e = locc .getExpr ( ) and
683+ outcome = locc .getOutcome ( )
684+ )
685+ }
686+
687+ /** A comparison against a list of compile-time constants. */
688+ abstract class ListOfConstantsComparison extends Guard {
689+ Expr e ;
690+ boolean outcome ;
691+
692+ ListOfConstantsComparison ( ) {
693+ exists ( this ) and
694+ outcome = [ true , false ]
695+ }
696+
697+ Expr getExpr ( ) { result = e }
698+
699+ boolean getOutcome ( ) { result = outcome }
700+ }
701+
702+ /**
703+ * An invocation of `java.util.List.contains` where the qualifier contains only
704+ * compile-time constants.
705+ */
706+ private class JavaUtilListOfConstantsContains extends ListOfConstantsComparison {
707+ JavaUtilListOfConstantsContains ( ) {
708+ exists ( MethodCall mc , Method m | mc .getMethod ( ) = m |
709+ m .hasName ( "contains" ) and
710+ m .getDeclaringType ( ) .getSourceDeclaration ( ) .hasQualifiedName ( "java.util" , "List" ) and
711+ DataFlow:: localFlow ( any ( JavaUtilListOfConstants loc ) , DataFlow:: exprNode ( mc .getQualifier ( ) ) ) and
712+ this = mc and
713+ e = mc .getArgument ( 0 ) and
714+ outcome = true
715+ )
716+ }
717+ }
718+
719+ /**
720+ * An instance of `java.util.List` which contains only compile-time constants.
721+ */
722+ abstract class JavaUtilListOfConstants extends DataFlow:: Node { }
723+
724+ /**
725+ * An invocation of `java.util.List.of` which constructs an (immutable) list
726+ * which contains only compile-time constants.
727+ */
728+ private class JavaUtilListOfConstantsCreatedWithListOf extends JavaUtilListOfConstants {
729+ JavaUtilListOfConstantsCreatedWithListOf ( ) {
730+ exists ( MethodCall mc , Method m |
731+ m .hasName ( "of" ) and
732+ m .getDeclaringType ( ) .getSourceDeclaration ( ) .hasQualifiedName ( "java.util" , "List" ) and
733+ mc .getMethod ( ) = m and
734+ DataFlow:: localFlow ( DataFlow:: exprNode ( mc ) , this ) and
735+ (
736+ // List<String> allowlist = List.of("a", "b", "c")
737+ forall ( Expr e | e = mc .getAnArgument ( ) | e .isCompileTimeConstant ( ) )
738+ or
739+ // String[] a = {"a", "b", "c"};
740+ // List<String> allowlist = List.of(a)
741+ exists ( ArrayInit arr | DataFlow:: localExprFlow ( arr , mc .getArgument ( 0 ) ) |
742+ forall ( Expr e | e = arr .getAnInit ( ) | e .isCompileTimeConstant ( ) )
743+ )
744+ )
745+ )
746+ }
747+ }
0 commit comments