Skip to content

Commit 86fd7d5

Browse files
committed
Add modelling for binding paths and default models when those are used through fragments
1 parent e251725 commit 86fd7d5

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

javascript/frameworks/ui5/lib/advanced_security/javascript/frameworks/ui5/Bindings.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,8 @@ class BindingTarget extends TBindingTarget {
597597
this = TLateJavaScriptBindingTarget(target, _)
598598
or
599599
this = TEarlyJavaScriptPropertyBindingTarget(target, _)
600+
or
601+
this = TLateJavaScriptBindingTarget(target.(BindElementMethodCallNode).getReceiver(), _)
600602
) and
601603
result = target
602604
)
@@ -727,6 +729,22 @@ class Binding extends TBinding {
727729
)
728730
}
729731

732+
DataFlow::Node asDataFlowNode() {
733+
exists(DataFlow::Node target |
734+
(
735+
this = TEarlyJavaScriptPropertyBinding(_, target)
736+
or
737+
this = TLateJavaScriptPropertyBinding(_, target)
738+
or
739+
exists(BindElementMethodCallNode bindElementCall |
740+
target = bindElementCall.getReceiver() and
741+
this = TLateJavaScriptContextBinding(bindElementCall, _)
742+
)
743+
) and
744+
result = target
745+
)
746+
}
747+
730748
BindingPath getBindingPath() { result.getBinding() = this }
731749

732750
BindingTarget getBindingTarget() { result.getBinding() = this }

javascript/frameworks/ui5/lib/advanced_security/javascript/frameworks/ui5/Fragment.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,9 @@ class FragmentLoad extends InvokeNode, MethodCallNode {
4848
result = config.getAPropertyWrite("controller").getRhs()
4949
)
5050
}
51+
52+
DataFlow::ParameterNode getCallbackObjectReference() {
53+
//the load invoke node is actually just a part of the chained load.then.bind
54+
result = this.getAMemberCall(_).getABoundCallbackParameter(_, _)
55+
}
5156
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,25 @@ abstract class UI5ExternalModel extends UI5Model, RemoteFlowSource {
110110
abstract string getName();
111111
}
112112

113+
/** Default model which gains content from an SAP OData service (ie no model name is explicitly specified). */
114+
class DefaultODataServiceModel extends UI5ExternalModel {
115+
DefaultODataServiceModel() {
116+
exists(ExternalModelManifest model |
117+
//an OData default model exists
118+
model.getName() = "" and
119+
model.getDataSource() instanceof ODataDataSourceManifest and
120+
//therefore the bindElement calls that exist may be sources and also approximates the model itself
121+
this.getCalleeName() = "bindElement"
122+
)
123+
}
124+
125+
override string getSourceType() { result = "DefaultODataServiceModel" }
126+
127+
override string getName() { result = "" }
128+
129+
Binding asBinding() { result.getBindingTarget().asDataFlowNode() = this }
130+
}
131+
113132
/** Model which gains content from an SAP OData service. */
114133
class ODataServiceModel extends UI5ExternalModel {
115134
string modelName;

javascript/frameworks/ui5/lib/advanced_security/javascript/frameworks/ui5/UI5View.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,24 @@ abstract class UI5BindingPath extends BindingPath {
132132
not exists(controlSetModelCall.getArgument(1)) and
133133
not exists(this.getModelName())
134134
)
135+
or
136+
/* 5. There is no call to `setModel` at all and a default model exists that is related to the binding path this refers to */
137+
exists(DefaultODataServiceModel defaultModel |
138+
result = defaultModel and
139+
not exists(MethodCallNode viewSetModelCall | viewSetModelCall.getMethodName() = "setModel") and
140+
/*
141+
* this binding path can occur in a fragment that is the receiver object for the bindElement model approximation
142+
* i.e. checks that the default model is relevant
143+
*/
144+
145+
exists(FragmentLoad load |
146+
load.getCallbackObjectReference().flowsTo(defaultModel.asBinding().asDataFlowNode()) and
147+
load.getNameArgument()
148+
.getStringValue()
149+
.matches("%" +
150+
this.getLocation().getFile().getBaseName().replaceAll(".fragment.xml", "") + "%")
151+
)
152+
)
135153
)
136154
// and
137155
// /* This binding path and the resulting model should live inside the same webapp */

0 commit comments

Comments
 (0)