diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll deleted file mode 100644 index 274bab002211..000000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll +++ /dev/null @@ -1,225 +0,0 @@ -/** - * For internal use only. - * - * Provides predicates that expose the knowledge of models - * in the core CodeQL JavaScript libraries. - */ - -private import javascript -private import semmle.javascript.security.dataflow.XxeCustomizations -private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations -private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations -private import semmle.javascript.security.dataflow.ZipSlipCustomizations -private import semmle.javascript.security.dataflow.TaintedPathCustomizations -private import semmle.javascript.security.dataflow.CleartextLoggingCustomizations -private import semmle.javascript.security.dataflow.XpathInjectionCustomizations -private import semmle.javascript.security.dataflow.Xss::Shared as Xss -private import semmle.javascript.security.dataflow.StackTraceExposureCustomizations -private import semmle.javascript.security.dataflow.ClientSideUrlRedirectCustomizations -private import semmle.javascript.security.dataflow.CodeInjectionCustomizations -private import semmle.javascript.security.dataflow.RequestForgeryCustomizations -private import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsCustomizations -private import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentCustomizations -private import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassCustomizations -private import semmle.javascript.security.dataflow.CommandInjectionCustomizations -private import semmle.javascript.security.dataflow.PrototypePollutionCustomizations -private import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallCustomizations -private import semmle.javascript.security.dataflow.TaintedFormatStringCustomizations -private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations -private import semmle.javascript.security.dataflow.PostMessageStarCustomizations -private import semmle.javascript.security.dataflow.RegExpInjectionCustomizations -private import semmle.javascript.security.dataflow.SqlInjectionCustomizations -private import semmle.javascript.security.dataflow.InsecureRandomnessCustomizations -private import semmle.javascript.security.dataflow.XmlBombCustomizations -private import semmle.javascript.security.dataflow.InsufficientPasswordHashCustomizations -private import semmle.javascript.security.dataflow.HardcodedCredentialsCustomizations -private import semmle.javascript.security.dataflow.FileAccessToHttpCustomizations -private import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccessCustomizations -private import semmle.javascript.security.dataflow.UnsafeDeserializationCustomizations -private import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeCustomizations -private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations -private import semmle.javascript.security.dataflow.IndirectCommandInjectionCustomizations -private import semmle.javascript.security.dataflow.ConditionalBypassCustomizations -private import semmle.javascript.security.dataflow.HttpToFileAccessCustomizations -private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations -private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations -private import semmle.javascript.security.dataflow.CleartextStorageCustomizations -import FilteringReasons - -/** - * Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink. - */ -predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) { - exists(DataFlow::InvokeNode invk, DataFlow::Node known | - invk.getAnArgument() = n and invk.getAnArgument() = known and isKnownLibrarySink(known) - ) -} - -/** - * Holds if the node `n` is a known sink for the external API security query. - * - * This corresponds to known sinks from security queries whose sources include remote flow and - * DOM-based sources. - */ -predicate isKnownExternalApiQuerySink(DataFlow::Node n) { - n instanceof Xxe::Sink or - n instanceof TaintedPath::Sink or - n instanceof XpathInjection::Sink or - n instanceof Xss::Sink or - n instanceof ClientSideUrlRedirect::Sink or - n instanceof CodeInjection::Sink or - n instanceof RequestForgery::Sink or - n instanceof CorsMisconfigurationForCredentials::Sink or - n instanceof CommandInjection::Sink or - n instanceof PrototypePollution::Sink or - n instanceof UnvalidatedDynamicMethodCall::Sink or - n instanceof TaintedFormatString::Sink or - n instanceof NosqlInjection::Sink or - n instanceof PostMessageStar::Sink or - n instanceof RegExpInjection::Sink or - n instanceof SqlInjection::Sink or - n instanceof XmlBomb::Sink or - n instanceof ZipSlip::Sink or - n instanceof UnsafeDeserialization::Sink or - n instanceof ServerSideUrlRedirect::Sink or - n instanceof CleartextStorage::Sink or - n instanceof HttpToFileAccess::Sink -} - -/** DEPRECATED: Alias for isKnownExternalApiQuerySink */ -deprecated predicate isKnownExternalAPIQuerySink = isKnownExternalApiQuerySink/1; - -/** - * Holds if the node `n` is a known sink in a modeled library. - */ -predicate isKnownLibrarySink(DataFlow::Node n) { - isKnownExternalApiQuerySink(n) or - n instanceof CleartextLogging::Sink or - n instanceof StackTraceExposure::Sink or - n instanceof ShellCommandInjectionFromEnvironment::Sink or - n instanceof InsecureRandomness::Sink or - n instanceof FileAccessToHttp::Sink or - n instanceof IndirectCommandInjection::Sink -} - -/** - * Holds if the node `n` is known as the predecessor in a modeled flow step. - */ -predicate isKnownStepSrc(DataFlow::Node n) { - TaintTracking::sharedTaintStep(n, _) or - DataFlow::SharedFlowStep::step(n, _) or - DataFlow::SharedFlowStep::step(n, _, _, _) -} - -/** - * Holds if `n` is an argument to a function of a builtin object. - */ -private predicate isArgumentToBuiltinFunction(DataFlow::Node n, FilteringReason reason) { - exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk | - ( - builtin instanceof DataFlow::ArrayCreationNode and - reason instanceof ArgumentToArrayReason - or - builtin = - DataFlow::globalVarRef([ - "Map", "Set", "WeakMap", "WeakSet", "Number", "Object", "String", "Array", "Error", - "Math", "Boolean" - ]) and - reason instanceof ArgumentToBuiltinGlobalVarRefReason - ) - | - receiver = [builtin.getAnInvocation(), builtin] and - invk = [receiver, receiver.getAPropertyRead()].getAnInvocation() and - invk.getAnArgument() = n - ) - or - exists(Expr primitive, MethodCallExpr c | - primitive instanceof ConstantString or - primitive instanceof NumberLiteral or - primitive instanceof BooleanLiteral - | - c.calls(primitive, _) and - c.getAnArgument() = n.asExpr() and - reason instanceof ConstantReceiverReason - ) - or - exists(DataFlow::CallNode call | - call.getAnArgument() = n and - call.getCalleeName() = - [ - "indexOf", "hasOwnProperty", "substring", "isDecimal", "decode", "encode", "keys", "shift", - "values", "forEach", "toString", "slice", "splice", "push", "isArray", "sort" - ] and - reason instanceof BuiltinCallNameReason - ) -} - -predicate isOtherModeledArgument(DataFlow::Node n, FilteringReason reason) { - isArgumentToBuiltinFunction(n, reason) - or - any(LodashUnderscore::Member m).getACall().getAnArgument() = n and - reason instanceof LodashUnderscoreArgumentReason - or - any(JQuery::MethodCall m).getAnArgument() = n and - reason instanceof JQueryArgumentReason - or - exists(ClientRequest r | - r.getAnArgument() = n or n = r.getUrl() or n = r.getHost() or n = r.getADataNode() - ) and - reason instanceof ClientRequestReason - or - exists(PromiseDefinition p | - n = [p.getResolveParameter(), p.getRejectParameter()].getACall().getAnArgument() - ) and - reason instanceof PromiseDefinitionReason - or - n instanceof CryptographicKey and reason instanceof CryptographicKeyReason - or - any(CryptographicOperation op).getInput() = n and - reason instanceof CryptographicOperationFlowReason - or - exists(DataFlow::CallNode call | n = call.getAnArgument() | - call.getCalleeName() = getAStandardLoggerMethodName() and - reason instanceof LoggerMethodReason - or - call.getCalleeName() = ["setTimeout", "clearTimeout"] and - reason instanceof TimeoutReason - or - call.getReceiver() = DataFlow::globalVarRef(["localStorage", "sessionStorage"]) and - reason instanceof ReceiverStorageReason - or - call instanceof StringOps::StartsWith and reason instanceof StringStartsWithReason - or - call instanceof StringOps::EndsWith and reason instanceof StringEndsWithReason - or - call instanceof StringOps::RegExpTest and reason instanceof StringRegExpTestReason - or - call instanceof EventRegistration and reason instanceof EventRegistrationReason - or - call instanceof EventDispatch and reason instanceof EventDispatchReason - or - call = any(MembershipCandidate c).getTest() and - reason instanceof MembershipCandidateTestReason - or - call instanceof FileSystemAccess and reason instanceof FileSystemAccessReason - or - // TODO database accesses are less well defined than database query sinks, so this may cover unmodeled sinks on existing database models - [ - call, call.getAMethodCall() - /* command pattern where the query is built, and then exec'ed later */ ] instanceof - DatabaseAccess and - reason instanceof DatabaseAccessReason - or - call = DOM::domValueRef() and reason instanceof DomReason - or - call.getCalleeName() = "next" and - exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) and - reason instanceof NextFunctionCallReason - or - call = DataFlow::globalVarRef("dojo").getAPropertyRead("require").getACall() and - reason instanceof DojoRequireReason - ) - or - (exists(Base64::Decode d | n = d.getInput()) or exists(Base64::Encode d | n = d.getInput())) and - reason instanceof Base64ManipulationReason -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 7bd615df1392..74a5ca6256de 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -7,10 +7,46 @@ private import semmle.javascript.security.dataflow.SqlInjectionCustomizations private import semmle.javascript.security.dataflow.DomBasedXssCustomizations private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations private import semmle.javascript.security.dataflow.TaintedPathCustomizations -private import CoreKnowledge as CoreKnowledge private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles -private import StandardEndpointFilters as StandardEndpointFilters +private import semmle.javascript.security.dataflow.XxeCustomizations +private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations +private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations +private import semmle.javascript.security.dataflow.ZipSlipCustomizations +private import semmle.javascript.security.dataflow.TaintedPathCustomizations +private import semmle.javascript.security.dataflow.CleartextLoggingCustomizations +private import semmle.javascript.security.dataflow.XpathInjectionCustomizations +private import semmle.javascript.security.dataflow.Xss::Shared as Xss +private import semmle.javascript.security.dataflow.StackTraceExposureCustomizations +private import semmle.javascript.security.dataflow.ClientSideUrlRedirectCustomizations +private import semmle.javascript.security.dataflow.CodeInjectionCustomizations +private import semmle.javascript.security.dataflow.RequestForgeryCustomizations +private import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsCustomizations +private import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentCustomizations +private import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassCustomizations +private import semmle.javascript.security.dataflow.CommandInjectionCustomizations +private import semmle.javascript.security.dataflow.PrototypePollutionCustomizations +private import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallCustomizations +private import semmle.javascript.security.dataflow.TaintedFormatStringCustomizations +private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations +private import semmle.javascript.security.dataflow.PostMessageStarCustomizations +private import semmle.javascript.security.dataflow.RegExpInjectionCustomizations +private import semmle.javascript.security.dataflow.SqlInjectionCustomizations +private import semmle.javascript.security.dataflow.InsecureRandomnessCustomizations +private import semmle.javascript.security.dataflow.XmlBombCustomizations +private import semmle.javascript.security.dataflow.InsufficientPasswordHashCustomizations +private import semmle.javascript.security.dataflow.HardcodedCredentialsCustomizations +private import semmle.javascript.security.dataflow.FileAccessToHttpCustomizations +private import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccessCustomizations +private import semmle.javascript.security.dataflow.UnsafeDeserializationCustomizations +private import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeCustomizations +private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations +private import semmle.javascript.security.dataflow.IndirectCommandInjectionCustomizations +private import semmle.javascript.security.dataflow.ConditionalBypassCustomizations +private import semmle.javascript.security.dataflow.HttpToFileAccessCustomizations +private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations +private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations +private import semmle.javascript.security.dataflow.CleartextStorageCustomizations /** * A set of characteristics that a particular endpoint might have. This set of characteristics is used to make decisions @@ -61,6 +97,110 @@ abstract class EndpointCharacteristic extends string { final float mediumConfidence() { result = 0.6 } } +/* + * Helper predicates. + */ + +/** + * Holds if the node `n` is a known sink for the external API security query. + * + * This corresponds to known sinks from security queries whose sources include remote flow and + * DOM-based sources. + */ +private predicate isKnownExternalApiQuerySink(DataFlow::Node n) { + n instanceof Xxe::Sink or + n instanceof TaintedPath::Sink or + n instanceof XpathInjection::Sink or + n instanceof Xss::Sink or + n instanceof ClientSideUrlRedirect::Sink or + n instanceof CodeInjection::Sink or + n instanceof RequestForgery::Sink or + n instanceof CorsMisconfigurationForCredentials::Sink or + n instanceof CommandInjection::Sink or + n instanceof PrototypePollution::Sink or + n instanceof UnvalidatedDynamicMethodCall::Sink or + n instanceof TaintedFormatString::Sink or + n instanceof NosqlInjection::Sink or + n instanceof PostMessageStar::Sink or + n instanceof RegExpInjection::Sink or + n instanceof SqlInjection::Sink or + n instanceof XmlBomb::Sink or + n instanceof ZipSlip::Sink or + n instanceof UnsafeDeserialization::Sink or + n instanceof ServerSideUrlRedirect::Sink or + n instanceof CleartextStorage::Sink or + n instanceof HttpToFileAccess::Sink +} + +/** + * Holds if the node `n` is a known sink in a modeled library. + */ +private predicate isKnownLibrarySink(DataFlow::Node n) { + isKnownExternalApiQuerySink(n) or + n instanceof CleartextLogging::Sink or + n instanceof StackTraceExposure::Sink or + n instanceof ShellCommandInjectionFromEnvironment::Sink or + n instanceof InsecureRandomness::Sink or + n instanceof FileAccessToHttp::Sink or + n instanceof IndirectCommandInjection::Sink +} + +/** + * Holds if the node `n` is known as the predecessor in a modeled flow step. + */ +private predicate isKnownStepSrc(DataFlow::Node n) { + TaintTracking::sharedTaintStep(n, _) or + DataFlow::SharedFlowStep::step(n, _) or + DataFlow::SharedFlowStep::step(n, _, _, _) +} + +/** + * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. + * + * This includes direct arguments of likely external library calls as well as nested object + * literals within those calls. + */ +private predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { + n = getACallWithoutCallee().getAnArgument() + or + exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | + n = src.getAPropertyWrite().getRhs() + ) + or + exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | + n = arr.getAnElement() + ) +} + +/** + * Get calls for which we do not have the callee (i.e. the definition of the called function). This + * acts as a heuristic for identifying calls to external library functions. + */ +private DataFlow::CallNode getACallWithoutCallee() { + forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and + not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | + param.flowsTo(result.getCalleeNode()) and + callback = getACallback(param, DataFlow::TypeBackTracker::end()) + ) +} + +/** + * Gets a node that flows to callback-parameter `p`. + */ +private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { + t.start() and + result = p and + any(DataFlow::FunctionNode f).getLastParameter() = p and + exists(p.getACall()) + or + exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) +} + +/** + * Get calls which are likely to be to external non-built-in libraries. + */ +DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } + /* * Characteristics that are indicative of a sink. * NOTE: Initially each sink type has only one characteristic, which is that it's a sink of this type in the standard @@ -143,11 +283,19 @@ private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic { * negative samples for training. */ +/** + * A characteristic that is an indicator of not being a sink of any type, because it's a modeled argument. + */ +abstract class OtherModeledArgumentCharacteristic extends EndpointCharacteristic { + bindingset[this] + OtherModeledArgumentCharacteristic() { any() } +} + /** * A characteristic that is an indicator of not being a sink of any type, because it's an argument to a function of a * builtin object. */ -abstract private class ArgumentToBuiltinFunctionCharacteristic extends EndpointCharacteristic { +abstract private class ArgumentToBuiltinFunctionCharacteristic extends OtherModeledArgumentCharacteristic { bindingset[this] ArgumentToBuiltinFunctionCharacteristic() { any() } } @@ -187,15 +335,17 @@ abstract class LikelyNotASinkCharacteristic extends EndpointCharacteristic { } } -private class LodashUnderscore extends NotASinkCharacteristic { - LodashUnderscore() { this = "LodashUnderscoreArgument" } +private class LodashUnderscoreCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + LodashUnderscoreCharacteristic() { this = "LodashUnderscoreArgument" } override predicate getEndpoints(DataFlow::Node n) { any(LodashUnderscore::Member m).getACall().getAnArgument() = n } } -private class JQueryArgumentCharacteristic extends NotASinkCharacteristic { +private class JQueryArgumentCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { JQueryArgumentCharacteristic() { this = "JQueryArgument" } override predicate getEndpoints(DataFlow::Node n) { @@ -203,7 +353,8 @@ private class JQueryArgumentCharacteristic extends NotASinkCharacteristic { } } -private class ClientRequestCharacteristic extends NotASinkCharacteristic { +private class ClientRequestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { ClientRequestCharacteristic() { this = "ClientRequest" } override predicate getEndpoints(DataFlow::Node n) { @@ -213,7 +364,8 @@ private class ClientRequestCharacteristic extends NotASinkCharacteristic { } } -private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic { +private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { PromiseDefinitionCharacteristic() { this = "PromiseDefinition" } override predicate getEndpoints(DataFlow::Node n) { @@ -223,13 +375,15 @@ private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic { } } -private class CryptographicKeyCharacteristic extends NotASinkCharacteristic { +private class CryptographicKeyCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { CryptographicKeyCharacteristic() { this = "CryptographicKey" } override predicate getEndpoints(DataFlow::Node n) { n instanceof CryptographicKey } } -private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic { +private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { CryptographicOperationFlowCharacteristic() { this = "CryptographicOperationFlow" } override predicate getEndpoints(DataFlow::Node n) { @@ -237,7 +391,8 @@ private class CryptographicOperationFlowCharacteristic extends NotASinkCharacter } } -private class LoggerMethodCharacteristic extends NotASinkCharacteristic { +private class LoggerMethodCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { LoggerMethodCharacteristic() { this = "LoggerMethod" } override predicate getEndpoints(DataFlow::Node n) { @@ -247,7 +402,8 @@ private class LoggerMethodCharacteristic extends NotASinkCharacteristic { } } -private class TimeoutCharacteristic extends NotASinkCharacteristic { +private class TimeoutCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { TimeoutCharacteristic() { this = "Timeout" } override predicate getEndpoints(DataFlow::Node n) { @@ -257,7 +413,8 @@ private class TimeoutCharacteristic extends NotASinkCharacteristic { } } -private class ReceiverStorageCharacteristic extends NotASinkCharacteristic { +private class ReceiverStorageCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { ReceiverStorageCharacteristic() { this = "ReceiverStorage" } override predicate getEndpoints(DataFlow::Node n) { @@ -267,7 +424,8 @@ private class ReceiverStorageCharacteristic extends NotASinkCharacteristic { } } -private class StringStartsWithCharacteristic extends NotASinkCharacteristic { +private class StringStartsWithCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { StringStartsWithCharacteristic() { this = "StringStartsWith" } override predicate getEndpoints(DataFlow::Node n) { @@ -277,7 +435,8 @@ private class StringStartsWithCharacteristic extends NotASinkCharacteristic { } } -private class StringEndsWithCharacteristic extends NotASinkCharacteristic { +private class StringEndsWithCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { StringEndsWithCharacteristic() { this = "StringEndsWith" } override predicate getEndpoints(DataFlow::Node n) { @@ -285,7 +444,8 @@ private class StringEndsWithCharacteristic extends NotASinkCharacteristic { } } -private class StringRegExpTestCharacteristic extends NotASinkCharacteristic { +private class StringRegExpTestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { StringRegExpTestCharacteristic() { this = "StringRegExpTest" } override predicate getEndpoints(DataFlow::Node n) { @@ -295,7 +455,8 @@ private class StringRegExpTestCharacteristic extends NotASinkCharacteristic { } } -private class EventRegistrationCharacteristic extends NotASinkCharacteristic { +private class EventRegistrationCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { EventRegistrationCharacteristic() { this = "EventRegistration" } override predicate getEndpoints(DataFlow::Node n) { @@ -303,7 +464,8 @@ private class EventRegistrationCharacteristic extends NotASinkCharacteristic { } } -private class EventDispatchCharacteristic extends NotASinkCharacteristic { +private class EventDispatchCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { EventDispatchCharacteristic() { this = "EventDispatch" } override predicate getEndpoints(DataFlow::Node n) { @@ -311,7 +473,8 @@ private class EventDispatchCharacteristic extends NotASinkCharacteristic { } } -private class MembershipCandidateTestCharacteristic extends NotASinkCharacteristic { +private class MembershipCandidateTestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { MembershipCandidateTestCharacteristic() { this = "MembershipCandidateTest" } override predicate getEndpoints(DataFlow::Node n) { @@ -321,7 +484,8 @@ private class MembershipCandidateTestCharacteristic extends NotASinkCharacterist } } -private class FileSystemAccessCharacteristic extends NotASinkCharacteristic { +private class FileSystemAccessCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { FileSystemAccessCharacteristic() { this = "FileSystemAccess" } override predicate getEndpoints(DataFlow::Node n) { @@ -329,7 +493,8 @@ private class FileSystemAccessCharacteristic extends NotASinkCharacteristic { } } -private class DatabaseAccessCharacteristic extends NotASinkCharacteristic { +private class DatabaseAccessCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { DatabaseAccessCharacteristic() { this = "DatabaseAccess" } override predicate getEndpoints(DataFlow::Node n) { @@ -344,7 +509,7 @@ private class DatabaseAccessCharacteristic extends NotASinkCharacteristic { } } -private class DomCharacteristic extends NotASinkCharacteristic { +private class DomCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { DomCharacteristic() { this = "DOM" } override predicate getEndpoints(DataFlow::Node n) { @@ -352,7 +517,8 @@ private class DomCharacteristic extends NotASinkCharacteristic { } } -private class NextFunctionCallCharacteristic extends NotASinkCharacteristic { +private class NextFunctionCallCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { NextFunctionCallCharacteristic() { this = "NextFunctionCall" } override predicate getEndpoints(DataFlow::Node n) { @@ -363,7 +529,8 @@ private class NextFunctionCallCharacteristic extends NotASinkCharacteristic { } } -private class DojoRequireCharacteristic extends NotASinkCharacteristic { +private class DojoRequireCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { DojoRequireCharacteristic() { this = "DojoRequire" } override predicate getEndpoints(DataFlow::Node n) { @@ -373,7 +540,8 @@ private class DojoRequireCharacteristic extends NotASinkCharacteristic { } } -private class Base64ManipulationCharacteristic extends NotASinkCharacteristic { +private class Base64ManipulationCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { Base64ManipulationCharacteristic() { this = "Base64Manipulation" } override predicate getEndpoints(DataFlow::Node n) { @@ -460,7 +628,6 @@ abstract class EndpointFilterCharacteristic extends EndpointCharacteristic { /** * An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a sink of any type. - * Replaces https://github.com/github/codeql/blob/387e57546bf7352f7c1cfe781daa1a3799b7063e/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll#LL15C24-L15C24 */ abstract private class StandardEndpointFilterCharacteristic extends EndpointFilterCharacteristic { bindingset[this] @@ -475,7 +642,7 @@ abstract private class StandardEndpointFilterCharacteristic extends EndpointFilt } } -private class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic { +class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic { IsArgumentToModeledFunctionCharacteristic() { this = "argument to modeled function" } override predicate getEndpoints(DataFlow::Node n) { @@ -483,11 +650,13 @@ private class IsArgumentToModeledFunctionCharacteristic extends StandardEndpoint invk.getAnArgument() = n and invk.getAnArgument() = known and ( - CoreKnowledge::isKnownLibrarySink(known) + isKnownLibrarySink(known) or - CoreKnowledge::isKnownStepSrc(known) + isKnownStepSrc(known) or - CoreKnowledge::isOtherModeledArgument(known, _) + exists(OtherModeledArgumentCharacteristic characteristic | + characteristic.getEndpoints(known) + ) ) ) } @@ -586,10 +755,19 @@ private class DatabaseAccessCallHeuristicCharacteristic extends NosqlInjectionSi private class ModeledSinkCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { ModeledSinkCharacteristic() { this = "modeled sink" } + /** + * Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink. + */ + predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) { + exists(DataFlow::InvokeNode invk, DataFlow::Node known | + invk.getAnArgument() = n and invk.getAnArgument() = known and isKnownLibrarySink(known) + ) + } + override predicate getEndpoints(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove modeled sinks - CoreKnowledge::isArgumentToKnownLibrarySinkFunction(n) + isArgumentToKnownLibrarySinkFunction(n) ) } } @@ -600,7 +778,7 @@ private class PredecessorInModeledFlowStepCharacteristic extends NosqlInjectionS override predicate getEndpoints(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove common kinds of unlikely sinks - CoreKnowledge::isKnownStepSrc(n) + isKnownStepSrc(n) ) } } @@ -653,7 +831,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh // // ## Direct arguments to external library calls // - // The `StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter + // The `flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter // allows sink candidates which are within object literals or array literals, for example // `req.sendFile(_, { path: ENDPOINT })`. // @@ -676,7 +854,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not n = StandardEndpointFilters::getALikelyExternalLibraryCall().getAnArgument() and + not n = getALikelyExternalLibraryCall().getAnArgument() and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(nosql|query)") or SyntacticHeuristics::isArgTo(n, "(?i)(query)") @@ -745,7 +923,7 @@ private class NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteris // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(sql|query)") or SyntacticHeuristics::isArgTo(n, "(?i)(query)") or @@ -783,7 +961,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTainted // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(file|folder|dir|absolute)") or @@ -844,7 +1022,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssChar // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(html|innerhtml)") or diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll deleted file mode 100644 index 4b0cdb986e88..000000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll +++ /dev/null @@ -1,220 +0,0 @@ -/** - * For internal use only. - * - * Defines a set of reasons why a particular endpoint was filtered out. This set of reasons - * contains both reasons why an endpoint could be `NotASink` and reasons why an endpoint could be - * `LikelyNotASink`. The `NotASinkReason`s defined here are exhaustive, but the - * `LikelyNotASinkReason`s are not exhaustive. - */ -newtype TFilteringReason = - TIsArgumentToBuiltinFunctionReason() or - TLodashUnderscoreArgumentReason() or - TClientRequestReason() or - TPromiseDefinitionReason() or - TCryptographicKeyReason() or - TCryptographicOperationFlowReason() or - TLoggerMethodReason() or - TTimeoutReason() or - TReceiverStorageReason() or - TStringStartsWithReason() or - TStringEndsWithReason() or - TStringRegExpTestReason() or - TEventRegistrationReason() or - TEventDispatchReason() or - TMembershipCandidateTestReason() or - TFileSystemAccessReason() or - TDatabaseAccessReason() or - TDomReason() or - TNextFunctionCallReason() or - TArgumentToArrayReason() or - TArgumentToBuiltinGlobalVarRefReason() or - TConstantReceiverReason() or - TBuiltinCallNameReason() or - TBase64ManipulationReason() or - TJQueryArgumentReason() or - TDojoRequireReason() - -/** A reason why a particular endpoint was filtered out by the endpoint filters. */ -abstract class FilteringReason extends TFilteringReason { - abstract string getDescription(); - - abstract int getEncoding(); - - string toString() { result = getDescription() } -} - -/** - * A reason why a particular endpoint might be considered to be `NotASink`. - * - * An endpoint is `NotASink` if it has at least one `NotASinkReason`, it does not have any - * `LikelyNotASinkReason`s, and it is not a known sink. - */ -abstract class NotASinkReason extends FilteringReason { } - -/** - * A reason why a particular endpoint might be considered to be `LikelyNotASink`. - * - * An endpoint is `LikelyNotASink` if it has at least one `LikelyNotASinkReason` and it is not a - * known sink. - */ -abstract class LikelyNotASinkReason extends FilteringReason { } - -class IsArgumentToBuiltinFunctionReason extends NotASinkReason, TIsArgumentToBuiltinFunctionReason { - override string getDescription() { result = "IsArgumentToBuiltinFunction" } - - override int getEncoding() { result = 5 } -} - -class LodashUnderscoreArgumentReason extends NotASinkReason, TLodashUnderscoreArgumentReason { - override string getDescription() { result = "LodashUnderscoreArgument" } - - override int getEncoding() { result = 6 } -} - -class ClientRequestReason extends NotASinkReason, TClientRequestReason { - override string getDescription() { result = "ClientRequest" } - - override int getEncoding() { result = 7 } -} - -class PromiseDefinitionReason extends NotASinkReason, TPromiseDefinitionReason { - override string getDescription() { result = "PromiseDefinition" } - - override int getEncoding() { result = 8 } -} - -class CryptographicKeyReason extends NotASinkReason, TCryptographicKeyReason { - override string getDescription() { result = "CryptographicKey" } - - override int getEncoding() { result = 9 } -} - -class CryptographicOperationFlowReason extends NotASinkReason, TCryptographicOperationFlowReason { - override string getDescription() { result = "CryptographicOperationFlow" } - - override int getEncoding() { result = 10 } -} - -class LoggerMethodReason extends NotASinkReason, TLoggerMethodReason { - override string getDescription() { result = "LoggerMethod" } - - override int getEncoding() { result = 11 } -} - -class TimeoutReason extends NotASinkReason, TTimeoutReason { - override string getDescription() { result = "Timeout" } - - override int getEncoding() { result = 12 } -} - -class ReceiverStorageReason extends NotASinkReason, TReceiverStorageReason { - override string getDescription() { result = "ReceiverStorage" } - - override int getEncoding() { result = 13 } -} - -class StringStartsWithReason extends NotASinkReason, TStringStartsWithReason { - override string getDescription() { result = "StringStartsWith" } - - override int getEncoding() { result = 14 } -} - -class StringEndsWithReason extends NotASinkReason, TStringEndsWithReason { - override string getDescription() { result = "StringEndsWith" } - - override int getEncoding() { result = 15 } -} - -class StringRegExpTestReason extends NotASinkReason, TStringRegExpTestReason { - override string getDescription() { result = "StringRegExpTest" } - - override int getEncoding() { result = 16 } -} - -class EventRegistrationReason extends NotASinkReason, TEventRegistrationReason { - override string getDescription() { result = "EventRegistration" } - - override int getEncoding() { result = 17 } -} - -class EventDispatchReason extends NotASinkReason, TEventDispatchReason { - override string getDescription() { result = "EventDispatch" } - - override int getEncoding() { result = 18 } -} - -class MembershipCandidateTestReason extends NotASinkReason, TMembershipCandidateTestReason { - override string getDescription() { result = "MembershipCandidateTest" } - - override int getEncoding() { result = 19 } -} - -class FileSystemAccessReason extends NotASinkReason, TFileSystemAccessReason { - override string getDescription() { result = "FileSystemAccess" } - - override int getEncoding() { result = 20 } -} - -class DatabaseAccessReason extends NotASinkReason, TDatabaseAccessReason { - override string getDescription() { result = "DatabaseAccess" } - - override int getEncoding() { result = 21 } -} - -class DomReason extends NotASinkReason, TDomReason { - override string getDescription() { result = "DOM" } - - override int getEncoding() { result = 22 } -} - -/** DEPRECATED: Alias for DomReason */ -deprecated class DOMReason = DomReason; - -class NextFunctionCallReason extends NotASinkReason, TNextFunctionCallReason { - override string getDescription() { result = "NextFunctionCall" } - - override int getEncoding() { result = 23 } -} - -class ArgumentToArrayReason extends LikelyNotASinkReason, TArgumentToArrayReason { - override string getDescription() { result = "ArgumentToArray" } - - override int getEncoding() { result = 24 } -} - -class ArgumentToBuiltinGlobalVarRefReason extends LikelyNotASinkReason, - TArgumentToBuiltinGlobalVarRefReason { - override string getDescription() { result = "ArgumentToBuiltinGlobalVarRef" } - - override int getEncoding() { result = 25 } -} - -class ConstantReceiverReason extends NotASinkReason, TConstantReceiverReason { - override string getDescription() { result = "ConstantReceiver" } - - override int getEncoding() { result = 26 } -} - -class BuiltinCallNameReason extends NotASinkReason, TBuiltinCallNameReason { - override string getDescription() { result = "BuiltinCallName" } - - override int getEncoding() { result = 27 } -} - -class Base64ManipulationReason extends NotASinkReason, TBase64ManipulationReason { - override string getDescription() { result = "Base64Manipulation" } - - override int getEncoding() { result = 28 } -} - -class JQueryArgumentReason extends NotASinkReason, TJQueryArgumentReason { - override string getDescription() { result = "JQueryArgument" } - - override int getEncoding() { result = 29 } -} - -class DojoRequireReason extends NotASinkReason, TDojoRequireReason { - override string getDescription() { result = "DojoRequire" } - - override int getEncoding() { result = 30 } -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 85b3d14d7e93..f03631bfdcff 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -8,7 +8,6 @@ import javascript private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations import AdaptiveThreatModeling -private import CoreKnowledge as CoreKnowledge class NosqlInjectionAtmConfig extends AtmConfig { NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index f52e1898667c..14821404e6d0 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -7,7 +7,6 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.SqlInjectionCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge class SqlInjectionAtmConfig extends AtmConfig { SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll deleted file mode 100644 index 11041937a3a2..000000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll +++ /dev/null @@ -1,78 +0,0 @@ -/** - * For internal use only. - * - * Provides classes and predicates that are useful for endpoint filters. - * - * The standard use of this library is to make use of `isPotentialEffectiveSink/1` - */ - -private import javascript -private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles -private import semmle.javascript.heuristics.SyntacticHeuristics -private import CoreKnowledge as CoreKnowledge -import EndpointCharacteristics as EndpointCharacteristics - -/** - * Holds if the node `n` is an argument to a function that has a manual model. - */ -predicate isArgumentToModeledFunction(DataFlow::Node n) { - exists(DataFlow::InvokeNode invk, DataFlow::Node known | - invk.getAnArgument() = n and invk.getAnArgument() = known and isSomeModeledArgument(known) - ) -} - -/** - * Holds if the node `n` is an argument that has a manual model. - */ -predicate isSomeModeledArgument(DataFlow::Node n) { - CoreKnowledge::isKnownLibrarySink(n) or - CoreKnowledge::isKnownStepSrc(n) or - CoreKnowledge::isOtherModeledArgument(n, _) -} - -/** - * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. - * - * This includes direct arguments of likely external library calls as well as nested object - * literals within those calls. - */ -predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { - n = getACallWithoutCallee().getAnArgument() - or - exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | - n = src.getAPropertyWrite().getRhs() - ) - or - exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | - n = arr.getAnElement() - ) -} - -/** - * Get calls which are likely to be to external non-built-in libraries. - */ -DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } - -/** - * Gets a node that flows to callback-parameter `p`. - */ -private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { - t.start() and - result = p and - any(DataFlow::FunctionNode f).getLastParameter() = p and - exists(p.getACall()) - or - exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) -} - -/** - * Get calls for which we do not have the callee (i.e. the definition of the called function). This - * acts as a heuristic for identifying calls to external library functions. - */ -DataFlow::CallNode getACallWithoutCallee() { - forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and - not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | - param.flowsTo(result.getCalleeNode()) and - callback = getACallback(param, DataFlow::TypeBackTracker::end()) - ) -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index e83938071df8..302907820da7 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -7,7 +7,6 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.TaintedPathCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge class TaintedPathAtmConfig extends AtmConfig { TaintedPathAtmConfig() { this = "TaintedPathATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index 508cac4544fa..2cc848a7ea9f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -7,7 +7,6 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.DomBasedXssCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge class DomBasedXssAtmConfig extends AtmConfig { DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql index 6c1d88443d0d..9439fda8ab2b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql @@ -12,8 +12,8 @@ import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm import experimental.adaptivethreatmodeling.XssATM as XssAtm import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures -import experimental.adaptivethreatmodeling.StandardEndpointFilters as StandardEndpointFilters import extraction.NoFeaturizationRestrictionsConfig +private import experimental.adaptivethreatmodeling.EndpointCharacteristics as EndpointCharacteristics query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { ( @@ -21,7 +21,8 @@ query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, strin not exists(any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or not exists(any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or not exists(any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or - StandardEndpointFilters::isArgumentToModeledFunction(endpoint) + any(EndpointCharacteristics::IsArgumentToModeledFunctionCharacteristic characteristic) + .getEndpoints(endpoint) ) and EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql index 6c2928c74e00..da91ecf1b438 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql @@ -1,3 +1,3 @@ -import experimental.adaptivethreatmodeling.StandardEndpointFilters +import experimental.adaptivethreatmodeling.EndpointCharacteristics as EndpointCharacteristics -select getALikelyExternalLibraryCall() +select EndpointCharacteristics::getALikelyExternalLibraryCall()