Skip to content

Commit efd3470

Browse files
committed
Implement HandlerParameterData.getType/0
1 parent b5033bd commit efd3470

File tree

4 files changed

+92
-8
lines changed

4 files changed

+92
-8
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class ConstantOnlyTemplateLiteral extends TemplateLiteral {
2929
}
3030

3131
/**
32-
* Arguments of calls to `cds.log.{trace, debug, info, log, warn, error}`
32+
* Arguments of calls to `cds.log.{trace, debug, info, log, warn, error}`.
3333
*/
3434
class CdsLogSink extends DataFlow::Node {
3535
CdsLogSink() {
@@ -49,5 +49,12 @@ class CAPLogInjectionConfiguration extends LogInjectionConfiguration {
4949
start instanceof RemoteFlowSource
5050
}
5151

52+
override predicate isBarrier(DataFlow::Node node) {
53+
exists(HandlerParameterData handlerParameterData |
54+
node = handlerParameterData and
55+
not handlerParameterData.getType() = ["cds.String", "cds.LargeString"]
56+
)
57+
}
58+
5259
override predicate isSink(DataFlow::Node end) { end instanceof CdsLogSink }
5360
}

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ class CdlService extends CdlElement {
176176

177177
CdlEntity getAnEntity() { result = this.getEntity(_) }
178178

179+
CdlActionOrFunction getAnActionOrFunction() {
180+
result = this.getAnEvent() or result = this.getAnAction()
181+
}
182+
179183
CdlEvent getEvent(string eventName) {
180184
result.getName() = eventName and this.getName() = result.getName().splitAt(".", 0)
181185
}
@@ -227,13 +231,27 @@ class CdlEntity extends CdlElement {
227231
}
228232
}
229233

230-
class CdlEvent extends CdlElement {
234+
abstract class CdlActionOrFunction extends CdlElement {
235+
/**
236+
* Gets a parameter definition of this action with a given name.
237+
*/
238+
CdlAttribute getParameter(string paramName) {
239+
result = this.getPropValue("params").getPropValue(paramName)
240+
}
241+
242+
/**
243+
* Gets a parameter definition of this action.
244+
*/
245+
CdlAttribute getAParameter() { result = this.getParameter(_) }
246+
}
247+
248+
class CdlEvent extends CdlActionOrFunction {
231249
CdlEvent() { kind = CdlEventKind(this.getPropStringValue("kind")) }
232250

233251
string getBasename() { result = name.splitAt(".", count(name.indexOf("."))) }
234252
}
235253

236-
class CdlAction extends CdlElement {
254+
class CdlAction extends CdlActionOrFunction {
237255
CdlAction() { kind = CdlActionKind(this.getPropStringValue("kind")) }
238256

239257
predicate belongsToServiceWithNoAuthn() {
@@ -255,7 +273,10 @@ class CdlAttribute extends CdlObject {
255273
string name;
256274

257275
CdlAttribute() {
258-
exists(CdlElement entity | this = entity.getPropValue("elements").getPropValue(name))
276+
exists(CdlElement entity | this = entity.getPropValue("elements").getPropValue(name)) or
277+
exists(CdlActionOrFunction actionOrFunction |
278+
this = actionOrFunction.getPropValue("params").getPropValue(name)
279+
)
259280
}
260281

261282
override string getObjectLocationName() { result = getName() }

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import advanced_security.javascript.frameworks.cap.TypeTrackers
44
import advanced_security.javascript.frameworks.cap.PackageJson
55
import advanced_security.javascript.frameworks.cap.CDL
66
import advanced_security.javascript.frameworks.cap.CQL
7+
import advanced_security.javascript.frameworks.cap.RemoteFlowSources
78

89
/**
910
* ```js
@@ -701,3 +702,48 @@ class EntityReferenceFromCqlClause extends EntityReference, ExprNode {
701702

702703
override CdlEntity getCqlDefinition() { result = cql.getAccessingEntityDefinition() }
703704
}
705+
706+
/**
707+
* The `"data"` property of the handler's parameter that represents the request or message passed to this handler.
708+
* This property carries the user-provided payload provided to the CAP application. e.g.
709+
* ``` javascript
710+
* srv.on("send", async (msg) => {
711+
* const { payload } = msg.data;
712+
* })
713+
* ```
714+
* The `payload` carries the data that is sent to this application on the action or event named `send`.
715+
*/
716+
class HandlerParameterData instanceof PropRead {
717+
HandlerParameter handlerParameter;
718+
string dataName;
719+
720+
HandlerParameterData() {
721+
this = handlerParameter.getAPropertyRead("data").getAPropertyRead(dataName)
722+
}
723+
724+
/**
725+
* Gets the type of this handler parameter data.
726+
*/
727+
string getType() {
728+
/*
729+
* The result string is the type of this parameter if:
730+
* - There is an actionName which is this HandlerRegistration's action/function name, and
731+
* - The actionName in the CDS declaration has params with the same name of this parameter, and
732+
* - The result is the name of the type of the parameter.
733+
*/
734+
735+
exists(
736+
UserDefinedApplicationService userDefinedApplicationService,
737+
CdlActionOrFunction cdlActionOrFunction, HandlerRegistration handlerRegistration
738+
|
739+
handlerRegistration = userDefinedApplicationService.getAHandlerRegistration() and
740+
handlerRegistration = handlerParameter.getHandlerRegistration() and
741+
handlerRegistration.getAnEventName() = cdlActionOrFunction.getUnqualifiedName() and
742+
cdlActionOrFunction =
743+
userDefinedApplicationService.getCdsDeclaration().getAnActionOrFunction() and
744+
result = cdlActionOrFunction.getParameter(dataName).getType()
745+
)
746+
}
747+
748+
string toString() { result = this.(PropRead).toString() }
749+
}

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import advanced_security.javascript.frameworks.cap.CDS
1212
* All the parameters named `req` and `msg` are captured in the above example.
1313
*/
1414
class HandlerParameter extends ParameterNode, RemoteFlowSource {
15+
Handler handler;
16+
HandlerRegistration handlerRegistration;
17+
1518
HandlerParameter() {
16-
exists(
17-
Handler handler, HandlerRegistration handlerRegistration,
18-
UserDefinedApplicationService service
19-
|
19+
exists(UserDefinedApplicationService service |
2020
handler = handlerRegistration.getHandler() and
2121
this = handler.getParameter(0) and
2222
service.getAHandlerRegistration() = handlerRegistration and
@@ -27,6 +27,16 @@ class HandlerParameter extends ParameterNode, RemoteFlowSource {
2727
override string getSourceType() {
2828
result = "Parameter of an event handler belonging to an exposed service"
2929
}
30+
31+
/**
32+
* Gets the handler this is a parameter of.
33+
*/
34+
Handler getHandler() { result = handler }
35+
36+
/**
37+
* Gets the handler registration registering the handler it is a parameter of.
38+
*/
39+
HandlerRegistration getHandlerRegistration() { result = handlerRegistration }
3040
}
3141

3242
/**

0 commit comments

Comments
 (0)