mirror of
https://github.com/github/codeql.git
synced 2025-12-19 10:23:15 +01:00
Merge pull request #8604 from erik-krogh/httpNode
JS: refactor most library models away from AST nodes
This commit is contained in:
@@ -42,17 +42,19 @@ predicate isABuiltinEventName(string name) {
|
||||
* Holds if user code emits or broadcasts an event named `name`.
|
||||
*/
|
||||
predicate isAUserDefinedEventName(string name) {
|
||||
exists(string methodName, MethodCallExpr mce | methodName = "$emit" or methodName = "$broadcast" |
|
||||
mce.getArgument(0).mayHaveStringValue(name) and
|
||||
exists(string methodName, DataFlow::MethodCallNode mcn |
|
||||
methodName = "$emit" or methodName = "$broadcast"
|
||||
|
|
||||
mcn.getArgument(0).mayHaveStringValue(name) and
|
||||
(
|
||||
// dataflow based scope resolution
|
||||
mce = any(AngularJS::ScopeServiceReference scope).getAMethodCall(methodName)
|
||||
mcn = any(AngularJS::ScopeServiceReference scope).getAMethodCall(methodName)
|
||||
or
|
||||
// heuristic scope resolution: assume parameters like `$scope` or `$rootScope` are AngularJS scope objects
|
||||
exists(SimpleParameter param |
|
||||
exists(DataFlow::ParameterNode param |
|
||||
param.getName() = any(AngularJS::ScopeServiceReference scope).getName() and
|
||||
mce.getReceiver().mayReferToParameter(param) and
|
||||
mce.getMethodName() = methodName
|
||||
param.getAMethodCall() = mcn and
|
||||
mcn.getMethodName() = methodName
|
||||
)
|
||||
or
|
||||
// a call in an AngularJS expression
|
||||
@@ -64,7 +66,7 @@ predicate isAUserDefinedEventName(string name) {
|
||||
)
|
||||
}
|
||||
|
||||
from AngularJS::ScopeServiceReference scope, MethodCallExpr mce, string eventName
|
||||
from AngularJS::ScopeServiceReference scope, DataFlow::MethodCallNode mce, string eventName
|
||||
where
|
||||
mce = scope.getAMethodCall("$on") and
|
||||
mce.getArgument(0).mayHaveStringValue(eventName) and
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
import javascript
|
||||
|
||||
from AngularJS::InjectableFunction f, SimpleParameter p, string msg
|
||||
from AngularJS::InjectableFunction f, DataFlow::ParameterNode p, string msg
|
||||
where
|
||||
p = f.asFunction().getAParameter() and
|
||||
(
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
import javascript
|
||||
|
||||
from MethodCallExpr mce, AngularJS::BuiltinServiceReference service
|
||||
from DataFlow::MethodCallNode mce, AngularJS::BuiltinServiceReference service
|
||||
where
|
||||
service.getName() = "$sceProvider" and
|
||||
mce = service.getAMethodCall("enabled") and
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
import javascript
|
||||
|
||||
from AngularJS::ServiceReference compile, SimpleParameter elem, CallExpr c
|
||||
from AngularJS::ServiceReference compile, DataFlow::ParameterNode elem, DataFlow::CallNode c
|
||||
where
|
||||
compile.getName() = "$compile" and
|
||||
elem =
|
||||
@@ -24,7 +24,7 @@ where
|
||||
.(AngularJS::LinkFunction)
|
||||
.getElementParameter() and
|
||||
c = compile.getACall() and
|
||||
c.getArgument(0).mayReferToParameter(elem) and
|
||||
elem.flowsTo(c.getArgument(0)) and
|
||||
// don't flag $compile calls that specify a `maxPriority`
|
||||
c.getNumArgument() < 3
|
||||
select c, "This call to $compile may cause double compilation of '" + elem + "'."
|
||||
|
||||
@@ -12,16 +12,17 @@
|
||||
import javascript
|
||||
import semmle.javascript.RestrictedLocations
|
||||
|
||||
predicate isRepeatedDependency(AngularJS::InjectableFunction f, string name, AstNode location) {
|
||||
predicate isRepeatedDependency(AngularJS::InjectableFunction f, string name, DataFlow::Node node) {
|
||||
exists(int i, int j |
|
||||
i < j and
|
||||
exists(f.getDependencyDeclaration(i, name)) and
|
||||
location = f.getDependencyDeclaration(j, name)
|
||||
node = f.getDependencyDeclaration(j, name)
|
||||
)
|
||||
}
|
||||
|
||||
from AngularJS::InjectableFunction f, AstNode node, string name
|
||||
from AngularJS::InjectableFunction f, DataFlow::Node node, string name
|
||||
where
|
||||
isRepeatedDependency(f, name, node) and
|
||||
not count(f.asFunction().getParameterByName(name)) > 1 // avoid duplicating reports from js/duplicate-parameter-name
|
||||
select f.asFunction().(FirstLineOf), "This function has a duplicate dependency '$@'.", node, name
|
||||
select f.asFunction().getFunction().(FirstLineOf), "This function has a duplicate dependency '$@'.",
|
||||
node, name
|
||||
|
||||
@@ -23,7 +23,7 @@ predicate isResourceUrlWhitelist(
|
||||
) {
|
||||
exists(AngularJS::ServiceReference service |
|
||||
service.getName() = "$sceDelegateProvider" and
|
||||
setupCall.asExpr() = service.getAMethodCall("resourceUrlWhitelist") and
|
||||
setupCall = service.getAMethodCall("resourceUrlWhitelist") and
|
||||
list.flowsTo(setupCall.getArgument(0))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
import javascript
|
||||
import semmle.javascript.RestrictedLocations
|
||||
|
||||
from AngularJS::InjectableFunction f, AstNode explicitInjection
|
||||
from AngularJS::InjectableFunction f, DataFlow::Node explicitInjection
|
||||
where
|
||||
count(f.getAnExplicitDependencyInjection()) > 1 and
|
||||
explicitInjection = f.getAnExplicitDependencyInjection()
|
||||
select f.asFunction().(FirstLineOf), "This function has $@ defined in multiple places.",
|
||||
explicitInjection, "dependency injections"
|
||||
select f.asFunction().getFunction().(FirstLineOf),
|
||||
"This function has $@ defined in multiple places.", explicitInjection, "dependency injections"
|
||||
|
||||
@@ -13,9 +13,9 @@ import javascript
|
||||
import Declarations.UnusedParameter
|
||||
import semmle.javascript.RestrictedLocations
|
||||
|
||||
predicate isUnusedParameter(Function f, string msg, Parameter parameter) {
|
||||
predicate isUnusedParameter(DataFlow::FunctionNode f, string msg, Parameter parameter) {
|
||||
exists(Variable pv |
|
||||
isUnused(f, parameter, pv, _) and
|
||||
isUnused(f.getFunction(), parameter, pv, _) and
|
||||
not isAnAccidentallyUnusedParameter(parameter) and // avoid double alerts
|
||||
msg = "Unused dependency " + pv.getName() + "."
|
||||
)
|
||||
|
||||
@@ -135,7 +135,7 @@ DataFlow::CallNode servesAPrivateFolder(string description) {
|
||||
*/
|
||||
Express::RouteSetup getAnExposingExpressSetup(string path) {
|
||||
result.isUseCall() and
|
||||
result.getArgument([0 .. 1]) = servesAPrivateFolder(path).getEnclosingExpr()
|
||||
result.getArgument([0 .. 1]) = servesAPrivateFolder(path)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,7 +149,7 @@ DataFlow::CallNode getAnExposingServeSetup(string path) {
|
||||
|
||||
from DataFlow::Node node, string path
|
||||
where
|
||||
node = getAnExposingExpressSetup(path).flow()
|
||||
node = getAnExposingExpressSetup(path)
|
||||
or
|
||||
node = getAnExposingServeSetup(path)
|
||||
select node, "Serves " + path + ", which can contain private information."
|
||||
|
||||
@@ -19,7 +19,7 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
not source.getNode().asExpr() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash
|
||||
not source.getNode() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash
|
||||
select sink.getNode(), source, sink,
|
||||
"Sensitive data from $@ is used in a broken or weak cryptographic algorithm.", source.getNode(),
|
||||
source.getNode().(Source).describe()
|
||||
|
||||
@@ -15,13 +15,13 @@ import javascript
|
||||
|
||||
from
|
||||
Routing::RouteSetup setup, Routing::RouteHandler handler, HTTP::RequestInputAccess input,
|
||||
SensitiveExpr sensitive
|
||||
SensitiveNode sensitive
|
||||
where
|
||||
setup.getOwnHttpMethod() = "GET" and
|
||||
setup.getAChild+() = handler and
|
||||
input.getRouteHandler() = handler.getFunction() and
|
||||
input.getKind() = "parameter" and
|
||||
input.(DataFlow::SourceNode).flowsToExpr(sensitive) and
|
||||
input.(DataFlow::SourceNode).flowsTo(sensitive) and
|
||||
not sensitive.getClassification() = SensitiveDataClassification::id()
|
||||
select input, "$@ for GET requests uses query parameter as sensitive data.", handler,
|
||||
"Route handler"
|
||||
|
||||
@@ -77,7 +77,7 @@ private module StandardPoIs {
|
||||
UnpromotedRouteSetupPoI() { this = "UnpromotedRouteSetupPoI" }
|
||||
|
||||
override predicate is(Node l0) {
|
||||
l0 instanceof HTTP::RouteSetupCandidate and not l0.asExpr() instanceof HTTP::RouteSetup
|
||||
l0 instanceof HTTP::RouteSetupCandidate and not l0 instanceof HTTP::RouteSetup
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import CandidateTracking
|
||||
|
||||
from HTTP::RouteSetupCandidate setup
|
||||
where
|
||||
not setup.asExpr() instanceof HTTP::RouteSetup and
|
||||
not setup instanceof HTTP::RouteSetup and
|
||||
exists(HTTP::RouteHandlerCandidate rh |
|
||||
track(rh, DataFlow::TypeTracker::end()).flowsTo(setup.getARouteHandlerArg())
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user