Skip to content

Commit b05963e

Browse files
committed
Final draft
1 parent 4779663 commit b05963e

File tree

4 files changed

+145
-32
lines changed

4 files changed

+145
-32
lines changed

javascript/frameworks/ui5/ext/ui5.model.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ extensions:
9999
- ["CustomControllerGetOwnerComponentEventBusSubscriptionHandlerDataParameter", "CustomControllerGetOwnerComponentEventBusSubscribe", "Argument[2].Parameter[2]"]
100100
- ["CustomComponent", "Component", "Member[extend]"]
101101
- ["CustomRenderer", "Renderer", "Member[extend]"]
102+
- ["ViewReference", "CustomController", "Member[getView].ReturnValue"]
103+
- ["ControlReference", "ViewReference", "Member[byId].ReturnValue"]
102104

103105
- addsTo:
104106
pack: codeql/javascript-all

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,16 +343,20 @@ class ControlReference extends Reference {
343343
string controlId;
344344

345345
ControlReference() {
346-
this.getArgument(0).getALocalSource().getStringValue() = controlId and
347-
(
348-
exists(CustomController controller |
349-
this = controller.getAViewReference().getAMemberCall("byId") or
350-
this = controller.getAThisNode().getAMemberCall("byId")
351-
)
352-
or
353-
exists(SapUiCore sapUiCore | this = sapUiCore.getAMemberCall("byId"))
354-
)
355-
}
346+
this.getArgument(0).getALocalSource().getStringValue() = controlId
347+
/*
348+
* and
349+
* (
350+
* exists(CustomController controller |
351+
* this = controller.getAViewReference().getAMemberCall("byId") or
352+
* this = controller.getAThisNode().getAMemberCall("byId")
353+
* )
354+
* or
355+
* exists(SapUiCore sapUiCore | this = sapUiCore.getAMemberCall("byId"))
356+
* )
357+
*/
358+
359+
}
356360

357361
CustomControl getDefinition() {
358362
exists(UI5Control controlDeclaration |

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,3 +916,30 @@ class UI5Handler extends FunctionNode {
916916

917917
UI5Control getControl() { result = control }
918918
}
919+
920+
/**
921+
* Models controller references in event handlers as types
922+
*/
923+
overlay[local?]
924+
class ControlTypeInHandlerModel extends ModelInput::TypeModel {
925+
override DataFlow::CallNode getASource(string type) {
926+
// oEvent.getSource() is of the type of the Control calling the handler
927+
// exists(UI5Handler h |
928+
// type = h.getControl().getImportPath() and
929+
// result.getCalleeName() = "getSource" and
930+
// result.getReceiver().getALocalSource() = h.getParameter(0)
931+
// )
932+
// or
933+
// this.getView().byId("id") is of the type of the Control with id="id"
934+
exists(UI5Control c |
935+
type = c.getImportPath() and
936+
result = c.getAReference()
937+
)
938+
}
939+
940+
/**
941+
* Prevents model pruning for `ControlType`types
942+
*/
943+
bindingset[type]
944+
override predicate isTypeUsed(string type) { any() }
945+
}
Lines changed: 102 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,105 @@
11
nodes
2-
| webapp/controller/app.controller.js:26:11:26:15 | value |
3-
| webapp/controller/app.controller.js:26:19:26:35 | oInput.getValue() |
4-
| webapp/controller/app.controller.js:27:45:27:62 | { message: value } |
5-
| webapp/controller/app.controller.js:27:56:27:60 | value |
6-
| webapp/controller/app.controller.js:30:34:30:38 | model |
7-
| webapp/controller/app.controller.js:32:30:32:34 | model |
8-
| webapp/controller/app.controller.js:32:30:32:42 | model.message |
9-
| webapp/view/app.view.xml:5:3:8:29 | value={/input} |
10-
| webapp/view/app.view.xml:11:3:12:37 | content={/output1} |
2+
| webapp/controller/App1.controller.js:26:11:26:15 | value |
3+
| webapp/controller/App1.controller.js:26:19:26:35 | oInput.getValue() |
4+
| webapp/controller/App1.controller.js:27:45:27:62 | { message: value } |
5+
| webapp/controller/App1.controller.js:27:56:27:60 | value |
6+
| webapp/controller/App1.controller.js:30:34:30:38 | model |
7+
| webapp/controller/App1.controller.js:32:30:32:34 | model |
8+
| webapp/controller/App1.controller.js:32:30:32:42 | model.message |
9+
| webapp/controller/App2.controller.js:26:11:26:15 | value |
10+
| webapp/controller/App2.controller.js:26:19:26:35 | oInput.getValue() |
11+
| webapp/controller/App2.controller.js:27:45:27:62 | { message: value } |
12+
| webapp/controller/App2.controller.js:27:56:27:60 | value |
13+
| webapp/controller/App2.controller.js:30:34:30:38 | model |
14+
| webapp/controller/App2.controller.js:32:30:32:34 | model |
15+
| webapp/controller/App2.controller.js:32:30:32:42 | model.message |
16+
| webapp/controller/App3.controller.js:25:11:25:15 | value |
17+
| webapp/controller/App3.controller.js:25:19:25:35 | oInput.getValue() |
18+
| webapp/controller/App3.controller.js:26:45:26:62 | { message: value } |
19+
| webapp/controller/App3.controller.js:26:56:26:60 | value |
20+
| webapp/controller/App4.controller.js:24:34:24:38 | model |
21+
| webapp/controller/App4.controller.js:26:30:26:34 | model |
22+
| webapp/controller/App4.controller.js:26:30:26:42 | model.message |
23+
| webapp/view/App1.view.xml:5:3:8:29 | value={/input} |
24+
| webapp/view/App1.view.xml:11:3:12:37 | content={/output1} |
25+
| webapp/view/App2.view.xml:5:3:8:29 | value={/input} |
26+
| webapp/view/App2.view.xml:11:3:12:37 | content={/output1} |
27+
| webapp/view/App3.view.xml:5:3:8:29 | value={/input} |
28+
| webapp/view/App4.view.xml:5:3:6:37 | content={/output1} |
1129
edges
12-
| webapp/controller/app.controller.js:15:9:15:19 | input: null | webapp/view/app.view.xml:5:3:8:29 | value={/input} |
13-
| webapp/controller/app.controller.js:16:9:16:21 | output1: null | webapp/view/app.view.xml:11:3:12:37 | content={/output1} |
14-
| webapp/controller/app.controller.js:18:20:18:39 | new JSONModel(oData) | webapp/view/app.view.xml:11:3:12:37 | content={/output1} |
15-
| webapp/controller/app.controller.js:26:11:26:15 | value | webapp/controller/app.controller.js:27:56:27:60 | value |
16-
| webapp/controller/app.controller.js:26:19:26:35 | oInput.getValue() | webapp/controller/app.controller.js:26:11:26:15 | value |
17-
| webapp/controller/app.controller.js:27:45:27:62 | { message: value } | webapp/controller/app.controller.js:30:34:30:38 | model |
18-
| webapp/controller/app.controller.js:27:56:27:60 | value | webapp/controller/app.controller.js:27:45:27:62 | { message: value } |
19-
| webapp/controller/app.controller.js:30:34:30:38 | model | webapp/controller/app.controller.js:32:30:32:34 | model |
20-
| webapp/controller/app.controller.js:32:30:32:34 | model | webapp/controller/app.controller.js:32:30:32:42 | model.message |
21-
| webapp/view/app.view.xml:5:3:8:29 | value={/input} | webapp/controller/app.controller.js:15:9:15:19 | input: null |
22-
| webapp/view/app.view.xml:5:3:8:29 | value={/input} | webapp/controller/app.controller.js:18:20:18:39 | new JSONModel(oData) |
23-
| webapp/view/app.view.xml:11:3:12:37 | content={/output1} | webapp/controller/app.controller.js:16:9:16:21 | output1: null |
30+
| webapp/controller/App1.controller.js:15:9:15:19 | input: null | webapp/view/App1.view.xml:5:3:8:29 | value={/input} |
31+
| webapp/controller/App1.controller.js:15:9:15:19 | input: null | webapp/view/App2.view.xml:5:3:8:29 | value={/input} |
32+
| webapp/controller/App1.controller.js:15:9:15:19 | input: null | webapp/view/App3.view.xml:5:3:8:29 | value={/input} |
33+
| webapp/controller/App1.controller.js:16:9:16:21 | output1: null | webapp/view/App1.view.xml:11:3:12:37 | content={/output1} |
34+
| webapp/controller/App1.controller.js:16:9:16:21 | output1: null | webapp/view/App2.view.xml:11:3:12:37 | content={/output1} |
35+
| webapp/controller/App1.controller.js:16:9:16:21 | output1: null | webapp/view/App4.view.xml:5:3:6:37 | content={/output1} |
36+
| webapp/controller/App1.controller.js:18:20:18:39 | new JSONModel(oData) | webapp/view/App1.view.xml:11:3:12:37 | content={/output1} |
37+
| webapp/controller/App1.controller.js:26:11:26:15 | value | webapp/controller/App1.controller.js:27:56:27:60 | value |
38+
| webapp/controller/App1.controller.js:26:19:26:35 | oInput.getValue() | webapp/controller/App1.controller.js:26:11:26:15 | value |
39+
| webapp/controller/App1.controller.js:27:45:27:62 | { message: value } | webapp/controller/App1.controller.js:30:34:30:38 | model |
40+
| webapp/controller/App1.controller.js:27:56:27:60 | value | webapp/controller/App1.controller.js:27:45:27:62 | { message: value } |
41+
| webapp/controller/App1.controller.js:30:34:30:38 | model | webapp/controller/App1.controller.js:32:30:32:34 | model |
42+
| webapp/controller/App1.controller.js:32:30:32:34 | model | webapp/controller/App1.controller.js:32:30:32:42 | model.message |
43+
| webapp/controller/App2.controller.js:15:9:15:19 | input: null | webapp/view/App1.view.xml:5:3:8:29 | value={/input} |
44+
| webapp/controller/App2.controller.js:15:9:15:19 | input: null | webapp/view/App2.view.xml:5:3:8:29 | value={/input} |
45+
| webapp/controller/App2.controller.js:15:9:15:19 | input: null | webapp/view/App3.view.xml:5:3:8:29 | value={/input} |
46+
| webapp/controller/App2.controller.js:16:9:16:21 | output1: null | webapp/view/App1.view.xml:11:3:12:37 | content={/output1} |
47+
| webapp/controller/App2.controller.js:16:9:16:21 | output1: null | webapp/view/App2.view.xml:11:3:12:37 | content={/output1} |
48+
| webapp/controller/App2.controller.js:16:9:16:21 | output1: null | webapp/view/App4.view.xml:5:3:6:37 | content={/output1} |
49+
| webapp/controller/App2.controller.js:18:20:18:39 | new JSONModel(oData) | webapp/view/App2.view.xml:11:3:12:37 | content={/output1} |
50+
| webapp/controller/App2.controller.js:26:11:26:15 | value | webapp/controller/App2.controller.js:27:56:27:60 | value |
51+
| webapp/controller/App2.controller.js:26:19:26:35 | oInput.getValue() | webapp/controller/App2.controller.js:26:11:26:15 | value |
52+
| webapp/controller/App2.controller.js:27:45:27:62 | { message: value } | webapp/controller/App2.controller.js:30:34:30:38 | model |
53+
| webapp/controller/App2.controller.js:27:56:27:60 | value | webapp/controller/App2.controller.js:27:45:27:62 | { message: value } |
54+
| webapp/controller/App2.controller.js:30:34:30:38 | model | webapp/controller/App2.controller.js:32:30:32:34 | model |
55+
| webapp/controller/App2.controller.js:32:30:32:34 | model | webapp/controller/App2.controller.js:32:30:32:42 | model.message |
56+
| webapp/controller/App3.controller.js:15:9:15:19 | input: null | webapp/view/App1.view.xml:5:3:8:29 | value={/input} |
57+
| webapp/controller/App3.controller.js:15:9:15:19 | input: null | webapp/view/App2.view.xml:5:3:8:29 | value={/input} |
58+
| webapp/controller/App3.controller.js:15:9:15:19 | input: null | webapp/view/App3.view.xml:5:3:8:29 | value={/input} |
59+
| webapp/controller/App3.controller.js:16:9:16:21 | output1: null | webapp/view/App1.view.xml:11:3:12:37 | content={/output1} |
60+
| webapp/controller/App3.controller.js:16:9:16:21 | output1: null | webapp/view/App2.view.xml:11:3:12:37 | content={/output1} |
61+
| webapp/controller/App3.controller.js:16:9:16:21 | output1: null | webapp/view/App4.view.xml:5:3:6:37 | content={/output1} |
62+
| webapp/controller/App3.controller.js:25:11:25:15 | value | webapp/controller/App3.controller.js:26:56:26:60 | value |
63+
| webapp/controller/App3.controller.js:25:19:25:35 | oInput.getValue() | webapp/controller/App3.controller.js:25:11:25:15 | value |
64+
| webapp/controller/App3.controller.js:26:45:26:62 | { message: value } | webapp/controller/App4.controller.js:24:34:24:38 | model |
65+
| webapp/controller/App3.controller.js:26:56:26:60 | value | webapp/controller/App3.controller.js:26:45:26:62 | { message: value } |
66+
| webapp/controller/App4.controller.js:15:9:15:19 | input: null | webapp/view/App1.view.xml:5:3:8:29 | value={/input} |
67+
| webapp/controller/App4.controller.js:15:9:15:19 | input: null | webapp/view/App2.view.xml:5:3:8:29 | value={/input} |
68+
| webapp/controller/App4.controller.js:15:9:15:19 | input: null | webapp/view/App3.view.xml:5:3:8:29 | value={/input} |
69+
| webapp/controller/App4.controller.js:16:9:16:21 | output1: null | webapp/view/App1.view.xml:11:3:12:37 | content={/output1} |
70+
| webapp/controller/App4.controller.js:16:9:16:21 | output1: null | webapp/view/App2.view.xml:11:3:12:37 | content={/output1} |
71+
| webapp/controller/App4.controller.js:16:9:16:21 | output1: null | webapp/view/App4.view.xml:5:3:6:37 | content={/output1} |
72+
| webapp/controller/App4.controller.js:18:20:18:39 | new JSONModel(oData) | webapp/view/App4.view.xml:5:3:6:37 | content={/output1} |
73+
| webapp/controller/App4.controller.js:24:34:24:38 | model | webapp/controller/App4.controller.js:26:30:26:34 | model |
74+
| webapp/controller/App4.controller.js:26:30:26:34 | model | webapp/controller/App4.controller.js:26:30:26:42 | model.message |
75+
| webapp/view/App1.view.xml:5:3:8:29 | value={/input} | webapp/controller/App1.controller.js:15:9:15:19 | input: null |
76+
| webapp/view/App1.view.xml:5:3:8:29 | value={/input} | webapp/controller/App1.controller.js:18:20:18:39 | new JSONModel(oData) |
77+
| webapp/view/App1.view.xml:5:3:8:29 | value={/input} | webapp/controller/App2.controller.js:15:9:15:19 | input: null |
78+
| webapp/view/App1.view.xml:5:3:8:29 | value={/input} | webapp/controller/App3.controller.js:15:9:15:19 | input: null |
79+
| webapp/view/App1.view.xml:5:3:8:29 | value={/input} | webapp/controller/App4.controller.js:15:9:15:19 | input: null |
80+
| webapp/view/App1.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App1.controller.js:16:9:16:21 | output1: null |
81+
| webapp/view/App1.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App2.controller.js:16:9:16:21 | output1: null |
82+
| webapp/view/App1.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App3.controller.js:16:9:16:21 | output1: null |
83+
| webapp/view/App1.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App4.controller.js:16:9:16:21 | output1: null |
84+
| webapp/view/App2.view.xml:5:3:8:29 | value={/input} | webapp/controller/App1.controller.js:15:9:15:19 | input: null |
85+
| webapp/view/App2.view.xml:5:3:8:29 | value={/input} | webapp/controller/App2.controller.js:15:9:15:19 | input: null |
86+
| webapp/view/App2.view.xml:5:3:8:29 | value={/input} | webapp/controller/App2.controller.js:18:20:18:39 | new JSONModel(oData) |
87+
| webapp/view/App2.view.xml:5:3:8:29 | value={/input} | webapp/controller/App3.controller.js:15:9:15:19 | input: null |
88+
| webapp/view/App2.view.xml:5:3:8:29 | value={/input} | webapp/controller/App4.controller.js:15:9:15:19 | input: null |
89+
| webapp/view/App2.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App1.controller.js:16:9:16:21 | output1: null |
90+
| webapp/view/App2.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App2.controller.js:16:9:16:21 | output1: null |
91+
| webapp/view/App2.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App3.controller.js:16:9:16:21 | output1: null |
92+
| webapp/view/App2.view.xml:11:3:12:37 | content={/output1} | webapp/controller/App4.controller.js:16:9:16:21 | output1: null |
93+
| webapp/view/App3.view.xml:5:3:8:29 | value={/input} | webapp/controller/App1.controller.js:15:9:15:19 | input: null |
94+
| webapp/view/App3.view.xml:5:3:8:29 | value={/input} | webapp/controller/App2.controller.js:15:9:15:19 | input: null |
95+
| webapp/view/App3.view.xml:5:3:8:29 | value={/input} | webapp/controller/App3.controller.js:15:9:15:19 | input: null |
96+
| webapp/view/App3.view.xml:5:3:8:29 | value={/input} | webapp/controller/App3.controller.js:18:20:18:39 | new JSONModel(oData) |
97+
| webapp/view/App3.view.xml:5:3:8:29 | value={/input} | webapp/controller/App4.controller.js:15:9:15:19 | input: null |
98+
| webapp/view/App4.view.xml:5:3:6:37 | content={/output1} | webapp/controller/App1.controller.js:16:9:16:21 | output1: null |
99+
| webapp/view/App4.view.xml:5:3:6:37 | content={/output1} | webapp/controller/App2.controller.js:16:9:16:21 | output1: null |
100+
| webapp/view/App4.view.xml:5:3:6:37 | content={/output1} | webapp/controller/App3.controller.js:16:9:16:21 | output1: null |
101+
| webapp/view/App4.view.xml:5:3:6:37 | content={/output1} | webapp/controller/App4.controller.js:16:9:16:21 | output1: null |
24102
#select
25-
| webapp/controller/app.controller.js:32:30:32:42 | model.message | webapp/controller/app.controller.js:26:19:26:35 | oInput.getValue() | webapp/controller/app.controller.js:32:30:32:42 | model.message | XSS vulnerability due to $@. | webapp/controller/app.controller.js:26:19:26:35 | oInput.getValue() | user-provided value |
103+
| webapp/controller/App1.controller.js:32:30:32:42 | model.message | webapp/controller/App1.controller.js:26:19:26:35 | oInput.getValue() | webapp/controller/App1.controller.js:32:30:32:42 | model.message | XSS vulnerability due to $@. | webapp/controller/App1.controller.js:26:19:26:35 | oInput.getValue() | user-provided value |
104+
| webapp/controller/App2.controller.js:32:30:32:42 | model.message | webapp/controller/App2.controller.js:26:19:26:35 | oInput.getValue() | webapp/controller/App2.controller.js:32:30:32:42 | model.message | XSS vulnerability due to $@. | webapp/controller/App2.controller.js:26:19:26:35 | oInput.getValue() | user-provided value |
105+
| webapp/controller/App4.controller.js:26:30:26:42 | model.message | webapp/controller/App3.controller.js:25:19:25:35 | oInput.getValue() | webapp/controller/App4.controller.js:26:30:26:42 | model.message | XSS vulnerability due to $@. | webapp/controller/App3.controller.js:25:19:25:35 | oInput.getValue() | user-provided value |

0 commit comments

Comments
 (0)