diff --git a/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll b/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll index ecfde3f26c0..2549bd796b2 100644 --- a/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll +++ b/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll @@ -43,7 +43,35 @@ class Configuration extends TaintTracking::Configuration { or exists(RegexExecution re | nodeFrom = re.getString() and nodeTo = re) or - stringManipulation(nodeFrom, nodeTo) + // String methods + exists(MethodCallNode call, string method_name | + nodeTo = call and call.getMethodName() = method_name + | + call.calls(nodeFrom, method_name) and + method_name in [ + "capitalize", "casefold", "center", "expandtabs", "format", "format_map", "join", + "ljust", "lstrip", "lower", "replace", "rjust", "rstrip", "strip", "swapcase", "title", + "upper", "zfill", "encode", "decode" + ] + or + method_name = "replace" and + nodeFrom = call.getArg(1) + or + method_name = "format" and + nodeFrom = call.getArg(_) + or + // str -> List[str] + call.calls(nodeFrom, method_name) and + method_name in ["partition", "rpartition", "rsplit", "split", "splitlines"] + or + // Iterable[str] -> str + method_name = "join" and + nodeFrom = call.getArg(0) + or + // Mapping[str, Any] -> str + method_name = "format_map" and + nodeFrom = call.getArg(0) + ) ) and stateFrom instanceof PreValidation and stateTo instanceof PostValidation