Skip to content

Commit 9912a37

Browse files
committed
Apply changes from review sync
refactor remoteflowsources
1 parent f9ea162 commit 9912a37

File tree

2 files changed

+33
-129
lines changed

2 files changed

+33
-129
lines changed

javascript/frameworks/cap/lib/advanced_security/javascript/frameworks/cap/CDS.qll

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -345,23 +345,30 @@ class HandlerRegistration extends MethodCallNode {
345345
predicate isAfter() { methodName = "after" }
346346
}
347347

348+
/**
349+
* A parameter of a handler
350+
*/
351+
class HandlerParameter instanceof ParameterNode {
352+
Handler handler;
353+
354+
HandlerParameter() { this = handler.getParameter(0) }
355+
356+
Handler getHandler() { result = handler }
357+
358+
string toString() { result = super.toString() }
359+
}
360+
348361
/**
349362
* The handler that implements a service's logic to deal with the incoming request or message when a certain event is fired.
350363
* It is the last argument to the method calls that registers the handler: either `srv.before`, `srv.on`, or `srv.after`.
351364
* Its first parameter is of type `cds.Event` and handles the event in an asynchronous manner,
352365
* or is of type `cds.Request` and handles the event synchronously.
353366
*/
354367
class Handler extends FunctionNode {
355-
UserDefinedApplicationService srv;
356368
HandlerRegistration handlerRegistration;
357369

358370
Handler() { this = handlerRegistration.getAnArgument() }
359371

360-
/**
361-
* Gets the service registering this handler.
362-
*/
363-
UserDefinedApplicationService getDefiningService() { result = srv }
364-
365372
/**
366373
* Gets a name of one of the event this handler is registered for.
367374
*/
@@ -376,6 +383,8 @@ class Handler extends FunctionNode {
376383
* Gets the request that this handler is registered for, as represented as its first parameter.
377384
*/
378385
CdsRequest getRequest() { result = this.getParameter(0) }
386+
387+
HandlerRegistration getHandlerRegistration() { result = handlerRegistration }
379388
}
380389

381390
class CdsRequest extends ParameterNode {
@@ -823,7 +832,7 @@ class HandlerParameterData instanceof PropRead {
823832
string dataName;
824833

825834
HandlerParameterData() {
826-
this = handlerParameter.getAPropertyRead("data").getAPropertyRead(dataName)
835+
this = handlerParameter.(SourceNode).getAPropertyRead("data").getAPropertyRead(dataName)
827836
}
828837

829838
/**
@@ -842,7 +851,7 @@ class HandlerParameterData instanceof PropRead {
842851
CdlActionOrFunction cdlActionOrFunction, HandlerRegistration handlerRegistration
843852
|
844853
handlerRegistration = userDefinedApplicationService.getAHandlerRegistration() and
845-
handlerRegistration = handlerParameter.getHandlerRegistration() and
854+
handlerRegistration = handlerParameter.getHandler().getHandlerRegistration() and
846855
handlerRegistration.getAnEventName() = cdlActionOrFunction.getUnqualifiedName() and
847856
cdlActionOrFunction =
848857
userDefinedApplicationService.getCdsDeclaration().getAnActionOrFunction() and

javascript/frameworks/cap/lib/advanced_security/javascript/frameworks/cap/RemoteFlowSources.qll

Lines changed: 16 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -2,134 +2,29 @@ import javascript
22
import advanced_security.javascript.frameworks.cap.CDS
33

44
/**
5-
* A parameter of a handler registered for a service on an event. e.g.
6-
* ```javascript
7-
* this.on("SomeEvent", "SomeEntity", (req) => { ... });
8-
* this.before("SomeEvent", "SomeEntity", (req, next) => { ... }); // only `req` is captured
9-
* SomeService.on("SomeEvent", "SomeEntity", (msg) => { ... });
10-
* SomeService.after("SomeEvent", "SomeEntity", (msg) => { ... });
5+
* Either a service is known and is exposed
6+
* or
7+
* there is a handler parameter that is not connected to a service
8+
* possibly due to cds compilation failure
9+
* or non explicit service references in source
10+
* for example:
1111
* ```
12-
* All the parameters named `req` and `msg` are captured in the above example.
13-
*
14-
* This REQUIRES that a `UserDefinedApplicationService` is explicitly defined.
15-
*/
16-
class HandlerParameter extends ParameterNode, RemoteFlowSource {
17-
Handler handler;
18-
HandlerRegistration handlerRegistration;
19-
20-
HandlerParameter() {
21-
exists(UserDefinedApplicationService service |
22-
handler = handlerRegistration.getHandler() and
23-
this = handler.getParameter(0) and
24-
service.getAHandlerRegistration() = handlerRegistration and
25-
service.isExposed()
26-
)
27-
}
28-
29-
override string getSourceType() {
30-
result = "Parameter of an event handler belonging to an exposed service"
31-
}
32-
33-
/**
34-
* Gets the handler this is a parameter of.
35-
*/
36-
Handler getHandler() { result = handler }
37-
38-
/**
39-
* Gets the handler registration registering the handler it is a parameter of.
40-
*/
41-
HandlerRegistration getHandlerRegistration() { result = handlerRegistration }
42-
}
43-
44-
/**
45-
* A service may be described only in a CDS file, but event handlers may still be registered in a format such as:
46-
* ```javascript
47-
* module.exports = srv => {
48-
* srv.before('CREATE', 'Media', req => { // an entity name is used to describe which to register this handler to.
49-
* ...
50-
* });
51-
* }
52-
* ```
53-
* parameters named `req` are captured in the above example.
54-
*
55-
* This REQUIRES that a CDS file has successfully compiled
56-
* AND that a service name is explicitly provided in the handler registration.
57-
*/
58-
class ServiceinCDSHandlerParameterWithName extends ParameterNode, RemoteFlowSource {
59-
ServiceinCDSHandlerParameterWithName() {
60-
exists(MethodCallNode m, CdlEntity entity, string entityName |
61-
entity.getName().regexpReplaceAll(".*\\.", "") = entityName and
62-
(
63-
m.getArgument(1).asExpr().getStringValue().regexpReplaceAll("'", "") = entityName
64-
or
65-
m.getArgument(1).asExpr().(ArrayExpr).getAnElement().toString() = entityName
66-
) and
67-
this = m.getArgument(m.getNumArgument() - 1).(FunctionNode).getParameter(0) and
68-
m.getMethodName() in ["on", "before", "after"]
69-
)
70-
}
71-
72-
override string getSourceType() {
73-
result = "Parameter of an event handler belonging to an exposed service defined in a cds file"
74-
}
75-
}
76-
77-
/**
78-
* A parameter of a handler registered for a service on an event. e.g.
79-
* ```javascript
8012
* cds.serve('./test-service').with((srv) => {
81-
* srv.before('READ', '*', (req) => req.reply([]))
13+
* srv.after('READ', req => req.target.data) //req
8214
* })
8315
* ```
84-
* The parameter named `req` is captured in the above example.
85-
*
86-
* This DOES NOT REQUIRE that a `UserDefinedApplicationService` is explicitly defined and
87-
* this also DOES NOT REQUIRE that the name is provided explicitly.
8816
*/
89-
class HandlerParameterImplicitService extends ParameterNode, RemoteFlowSource {
90-
Handler handler;
91-
HandlerRegistration handlerRegistration;
92-
93-
HandlerParameterImplicitService() {
94-
exists(ServiceInstanceFromServeWithParameter service |
95-
handler = handlerRegistration.getHandler() and
96-
this = handler.getParameter(0) and
97-
service.getAHandlerRegistration() = handlerRegistration and
98-
/*
99-
* this will otherwise duplicate on the case where we do actually know the
100-
* name from the cds file and it matches up
101-
* example:
102-
* ```
103-
* srv.before('READ', 'Service1', (req) => req.reply([]))
104-
* ```
105-
* where Service1 is also defined in:
106-
* Service1.cds
107-
* ```
108-
* {
109-
* "namespace": "sap.capire.test",
110-
* "definitions": {
111-
* "sap.capire.test.Test": {
112-
* "kind": "entity",
113-
* ...
114-
* ```
115-
* only relevant if you are using the specific type anyhow (as opposed to RemoteFlowSource)
116-
*/
117-
118-
not this instanceof ServiceinCDSHandlerParameterWithName
119-
)
17+
class HandlerParameterOfExposedService extends RemoteFlowSource, HandlerParameter {
18+
HandlerParameterOfExposedService() {
19+
this.getHandler().getHandlerRegistration().getService().getDefinition().isExposed()
20+
or
21+
/* no precise service definition is known */
22+
not exists(this.getHandler().getHandlerRegistration().getService().getDefinition())
12023
}
12124

25+
override string toString() { result = HandlerParameter.super.toString() }
26+
12227
override string getSourceType() {
123-
result = "Parameter of an event handler belonging to an implicitly defined service"
28+
result = "Parameter of an event handler belonging to an exposed service"
12429
}
125-
126-
/**
127-
* Gets the handler this is a parameter of.
128-
*/
129-
Handler getHandler() { result = handler }
130-
131-
/**
132-
* Gets the handler registration registering the handler it is a parameter of.
133-
*/
134-
HandlerRegistration getHandlerRegistration() { result = handlerRegistration }
13530
}

0 commit comments

Comments
 (0)