Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/javascript.sarif.expected

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ module UI5LogEntryToHttp implements DataFlow::StateConfigSig {
predicate isAdditionalFlowStep(
DataFlow::Node start, FlowState preState, DataFlow::Node end, FlowState postState
) {
UI5LogInjection::isAdditionalFlowStep(start, end) and
preState = postState
or
logArgumentToListener(start, end) and
preState = "not-logged-not-accessed" and
postState = "logged-and-accessed"
inSameWebApp(start.getFile(), end.getFile()) and
(
UI5LogInjection::isAdditionalFlowStep(start, end) and
preState = postState
or
logArgumentToListener(start, end) and
preState = "not-logged-not-accessed" and
postState = "logged-and-accessed"
)
}

predicate isSink(DataFlow::Node node, FlowState state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,36 @@ module UI5Xss implements DataFlow::ConfigSig {
}

predicate isAdditionalFlowStep(DataFlow::Node start, DataFlow::Node end) {
/* Already an additional flow step defined in `DomBasedXssQuery::Configuration` */
DomBasedXss::DomBasedXssConfig::isAdditionalFlowStep(start, _, end, _)
or
/* TODO: Legacy code */
/* Handler argument node to handler parameter */
exists(UI5Handler h |
start = h.getBindingPath().getNode() and
/*
* Ideally we would like to show an intermediate node where
* the handler is bound to a control, but there is no sourceNode there
* `end = h.getBindingPath() or start = h.getBindingPath()`
*/
inSameWebApp(start.getFile(), end.getFile()) and
(
/* Already an additional flow step defined in `DomBasedXssQuery::Configuration` */
DomBasedXss::DomBasedXssConfig::isAdditionalFlowStep(start, _, end, _)
or
/* TODO: Legacy code */
/* Handler argument node to handler parameter */
exists(UI5Handler h |
start = h.getBindingPath().getNode() and
/*
* Ideally we would like to show an intermediate node where
* the handler is bound to a control, but there is no sourceNode there
* `end = h.getBindingPath() or start = h.getBindingPath()`
*/

end = h.getParameter(0)
)
or
/* Flow from `setContent` to `getContent` of a control */
exists(
UI5Control control, DataFlow::MethodCallNode getContent, DataFlow::MethodCallNode setContent
|
control.asJsControl() = setContent.getReceiver().getALocalSource() and
control.asJsControl() = getContent.getReceiver().getALocalSource() and
setContent.getMethodName() = "setContent" and
getContent.getMethodName() = "getContent" and
start = setContent.getArgument(0) and
end = getContent and
not control.isHTMLSanitized()
end = h.getParameter(0)
)
or
/* Flow from `setContent` to `getContent` of a control */
exists(
UI5Control control, DataFlow::MethodCallNode getContent, DataFlow::MethodCallNode setContent
|
control.asJsControl() = setContent.getReceiver().getALocalSource() and
control.asJsControl() = getContent.getReceiver().getALocalSource() and
setContent.getMethodName() = "setContent" and
getContent.getMethodName() = "getContent" and
start = setContent.getArgument(0) and
end = getContent and
not control.isHTMLSanitized()
)
)
}
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ class LocalModelContentBoundBidirectionallyToHtmlISinkControl extends DomBasedXs
UI5Control getControlDeclaration() { result = controlDeclaration }
}

/**
* A local source for cases where the Control implementation is separate from the complete UI5 app.
*/
class LocalModelStringPropertySource extends DomBasedXss::Source {
LocalModelStringPropertySource() {
this = any(PropertyMetadata propMeta | propMeta.isUnrestrictedStringType())
}
}

Comment thread
mbaluda marked this conversation as resolved.
module UI5PathGraph<PathNodeSig ConfigPathNode, PathGraphSig<ConfigPathNode> ConfigPathGraph> {
private newtype TNode =
TUI5BindingPathNode(UI5BindingPath path) or
Expand Down Expand Up @@ -254,24 +263,27 @@ module TrackPlaceAtCallConfig implements DataFlow::ConfigSig {
* - [ ] Heuristic by prefix: not an attractive option since heuristics can fail
*/
predicate isAdditionalFlowStep(DataFlow::Node start, DataFlow::Node end) {
exists(DataFlow::PropWrite propWrite |
start = propWrite.getRhs() and
end = propWrite.getBase()
)
or
exists(DataFlow::MethodCallNode maybeAddingChildAPICall |
start = maybeAddingChildAPICall.getAnArgument() and
end = maybeAddingChildAPICall.getReceiver()
)
or
exists(DataFlow::MethodCallNode call |
start = call.getReceiver() and
end = call
)
or
exists(DataFlow::NewNode new |
start = new.getAnArgument() and
end = new
inSameWebApp(start.getFile(), end.getFile()) and
(
exists(DataFlow::PropWrite propWrite |
start = propWrite.getRhs() and
end = propWrite.getBase()
)
or
exists(DataFlow::MethodCallNode maybeAddingChildAPICall |
start = maybeAddingChildAPICall.getAnArgument() and
end = maybeAddingChildAPICall.getReceiver()
)
or
exists(DataFlow::MethodCallNode call |
start = call.getReceiver() and
end = call
)
or
exists(DataFlow::NewNode new |
start = new.getAnArgument() and
end = new
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ edges
| webapp/controls/Book.js:133:8:133:26 | oControl.getTitle() | webapp/controls/Book.js:132:7:134:15 | "<div>T ... </div>" |
#select
| webapp/controls/Book.js:132:7:134:15 | "<div>T ... </div>" | webapp/controller/App.Controller.js:23:25:23:47 | oSearch ... Value() | webapp/controls/Book.js:132:7:134:15 | "<div>T ... </div>" | XSS vulnerability due to $@. | webapp/controller/App.Controller.js:23:25:23:47 | oSearch ... Value() | user-provided value |
| webapp/controls/Book.js:132:7:134:15 | "<div>T ... </div>" | webapp/controls/Book.js:17:13:17:30 | { type: "string" } | webapp/controls/Book.js:132:7:134:15 | "<div>T ... </div>" | XSS vulnerability due to $@. | webapp/controls/Book.js:17:13:17:30 | { type: "string" } | user-provided value |
Comment thread
knewbury01 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ edges
| webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/controller/app.controller.js:11:26:11:45 | new JSONModel(oData) |
| webapp/view/app.view.xml:8:5:8:38 | text={/input} | webapp/controller/app.controller.js:9:17:9:27 | input: null |
#select
| webapp/control/xss.js:14:23:14:40 | oControl.getText() | webapp/control/xss.js:7:23:7:40 | { type: "string" } | webapp/control/xss.js:14:23:14:40 | oControl.getText() | XSS vulnerability due to $@. | webapp/control/xss.js:7:23:7:40 | { type: "string" } | user-provided value |
| webapp/control/xss.js:14:23:14:40 | oControl.getText() | webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/control/xss.js:14:23:14:40 | oControl.getText() | XSS vulnerability due to $@. | webapp/view/app.view.xml:5:5:7:28 | value={/input} | user-provided value |

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
nodes
| xss-custom-control-api3/webapp/control/xss.js:7:23:7:40 | { type: "string" } |
| xss-custom-control-api3/webapp/control/xss.js:8:24:8:41 | { type: "string" } |
| xss-custom-control-api3/webapp/control/xss.js:15:32:15:49 | oControl.getText() |
| xss-custom-control-api3/webapp/control/xss.js:16:32:16:50 | oControl.getText2() |
| xss-custom-control-api3/webapp/controller/app.controller.js:9:17:9:27 | input: null |
| xss-custom-control-api3/webapp/view/app.view.xml:5:5:7:28 | value={/input} |
| xss-custom-control-api3/webapp/view/app.view.xml:8:5:8:38 | text={/input} |
| xss-custom-control.api2/webapp/control/xss.js:7:23:7:40 | { type: "string" } |
| xss-custom-control.api2/webapp/control/xss.js:14:32:14:49 | oControl.getText() |
| xss-custom-control.api2/webapp/controller/app.controller.js:9:17:9:27 | input: null |
| xss-custom-control.api2/webapp/view/app.view.xml:5:5:7:28 | value={/input} |
| xss-custom-control.api2/webapp/view/app.view.xml:8:5:8:38 | text={/input} |
edges
| xss-custom-control-api3/webapp/control/xss.js:7:23:7:40 | { type: "string" } | xss-custom-control-api3/webapp/control/xss.js:15:32:15:49 | oControl.getText() |
| xss-custom-control-api3/webapp/control/xss.js:7:23:7:40 | { type: "string" } | xss-custom-control-api3/webapp/controller/app.controller.js:9:17:9:27 | input: null |
| xss-custom-control-api3/webapp/control/xss.js:8:24:8:41 | { type: "string" } | xss-custom-control-api3/webapp/control/xss.js:16:32:16:50 | oControl.getText2() |
| xss-custom-control-api3/webapp/controller/app.controller.js:9:17:9:27 | input: null | xss-custom-control-api3/webapp/control/xss.js:7:23:7:40 | { type: "string" } |
| xss-custom-control-api3/webapp/controller/app.controller.js:9:17:9:27 | input: null | xss-custom-control-api3/webapp/view/app.view.xml:5:5:7:28 | value={/input} |
| xss-custom-control-api3/webapp/controller/app.controller.js:9:17:9:27 | input: null | xss-custom-control-api3/webapp/view/app.view.xml:8:5:8:38 | text={/input} |
| xss-custom-control-api3/webapp/view/app.view.xml:5:5:7:28 | value={/input} | xss-custom-control-api3/webapp/controller/app.controller.js:9:17:9:27 | input: null |
| xss-custom-control-api3/webapp/view/app.view.xml:5:5:7:28 | value={/input} | xss-custom-control-api3/webapp/controller/app.controller.js:11:26:11:45 | new JSONModel(oData) |
| xss-custom-control-api3/webapp/view/app.view.xml:8:5:8:38 | text={/input} | xss-custom-control-api3/webapp/controller/app.controller.js:9:17:9:27 | input: null |
| xss-custom-control.api2/webapp/control/xss.js:7:23:7:40 | { type: "string" } | xss-custom-control.api2/webapp/control/xss.js:14:32:14:49 | oControl.getText() |
| xss-custom-control.api2/webapp/control/xss.js:7:23:7:40 | { type: "string" } | xss-custom-control.api2/webapp/controller/app.controller.js:9:17:9:27 | input: null |
| xss-custom-control.api2/webapp/controller/app.controller.js:9:17:9:27 | input: null | xss-custom-control.api2/webapp/control/xss.js:7:23:7:40 | { type: "string" } |
| xss-custom-control.api2/webapp/controller/app.controller.js:9:17:9:27 | input: null | xss-custom-control.api2/webapp/view/app.view.xml:5:5:7:28 | value={/input} |
| xss-custom-control.api2/webapp/controller/app.controller.js:9:17:9:27 | input: null | xss-custom-control.api2/webapp/view/app.view.xml:8:5:8:38 | text={/input} |
| xss-custom-control.api2/webapp/view/app.view.xml:5:5:7:28 | value={/input} | xss-custom-control.api2/webapp/controller/app.controller.js:9:17:9:27 | input: null |
| xss-custom-control.api2/webapp/view/app.view.xml:5:5:7:28 | value={/input} | xss-custom-control.api2/webapp/controller/app.controller.js:11:26:11:45 | new JSONModel(oData) |
| xss-custom-control.api2/webapp/view/app.view.xml:8:5:8:38 | text={/input} | xss-custom-control.api2/webapp/controller/app.controller.js:9:17:9:27 | input: null |
#select
| xss-custom-control-api3/webapp/control/xss.js:15:32:15:49 | oControl.getText() | xss-custom-control-api3/webapp/control/xss.js:7:23:7:40 | { type: "string" } | xss-custom-control-api3/webapp/control/xss.js:15:32:15:49 | oControl.getText() | XSS vulnerability due to $@. | xss-custom-control-api3/webapp/control/xss.js:7:23:7:40 | { type: "string" } | user-provided value |
| xss-custom-control-api3/webapp/control/xss.js:15:32:15:49 | oControl.getText() | xss-custom-control-api3/webapp/view/app.view.xml:5:5:7:28 | value={/input} | xss-custom-control-api3/webapp/control/xss.js:15:32:15:49 | oControl.getText() | XSS vulnerability due to $@. | xss-custom-control-api3/webapp/view/app.view.xml:5:5:7:28 | value={/input} | user-provided value |
| xss-custom-control-api3/webapp/control/xss.js:16:32:16:50 | oControl.getText2() | xss-custom-control-api3/webapp/control/xss.js:8:24:8:41 | { type: "string" } | xss-custom-control-api3/webapp/control/xss.js:16:32:16:50 | oControl.getText2() | XSS vulnerability due to $@. | xss-custom-control-api3/webapp/control/xss.js:8:24:8:41 | { type: "string" } | user-provided value |
| xss-custom-control.api2/webapp/control/xss.js:14:32:14:49 | oControl.getText() | xss-custom-control.api2/webapp/control/xss.js:7:23:7:40 | { type: "string" } | xss-custom-control.api2/webapp/control/xss.js:14:32:14:49 | oControl.getText() | XSS vulnerability due to $@. | xss-custom-control.api2/webapp/control/xss.js:7:23:7:40 | { type: "string" } | user-provided value |
| xss-custom-control.api2/webapp/control/xss.js:14:32:14:49 | oControl.getText() | xss-custom-control.api2/webapp/view/app.view.xml:5:5:7:28 | value={/input} | xss-custom-control.api2/webapp/control/xss.js:14:32:14:49 | oControl.getText() | XSS vulnerability due to $@. | xss-custom-control.api2/webapp/view/app.view.xml:5:5:7:28 | value={/input} | user-provided value |
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
sap.ui.define([
"sap/ui/core/Control"
], function (Control) {
return Control.extend("codeql-sap-js.control.xss", {
metadata: {
properties: {
text: { type: "string" },
text2: { type: "string" }
}
},
renderer: {
apiVersion: 2,
render: function (oRm, oControl) {
oRm.openStart("div", oControl);
oRm.unsafeHtml(oControl.getText()); // XSS sink RenderManager.unsafeHtml
Comment thread Fixed
Comment thread Dismissed
oRm.unsafeHtml(oControl.getText2()); // XSS sink RenderManager.unsafeHtml
Comment thread Fixed
Comment thread Dismissed
oRm.close("div");
}
}
});
})

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "sap-ui5-xss",
"version": "1.0.0",
"main": "index.js"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
specVersion: '3.0'
metadata:
name: sap-ui5-xss
type: application
framework:
name: SAPUI5
version: "1.115.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"
], function (Controller, JSONModel) {
"use strict"
return Controller.extend("codeql-sap-js.controller.app", {
onInit: function () {
var oData = {
input: null
};
var oModel = new JSONModel(oData);
this.getView().setModel(oModel);
}
});
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>

<head>

<meta charset="utf-8">
<title>SAPUI5 XSS</title>
<script src="https://sdk.openui5.org/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m"
data-sap-ui-onInit="module:codeql-sap-js/index"
data-sap-ui-resourceroots='{
"codeql-sap-js": "./"
}'>
</script>
</head>

<body class="sapUiBody" id="content">

</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
sap.ui.define([
"sap/ui/core/mvc/XMLView"
], function (XMLView) {
"use strict";
XMLView.create({
viewName: "codeql-sap-js.view.app"
}).then(function (oView) {
oView.placeAt("content");
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"sap.app": {
"id": "sap-ui5-xss"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<mvc:View controllerName="codeql-sap-js.controller.app"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
xmlns:xssControl="codeql-sap-js.control">
<Input placeholder="Enter Payload"
description="Try: &lt;img src=x onerror=alert(&quot;XSS&quot;)&gt;"
value="{/input}" /> <!--User input source sap.m.Input.value -->
<xssControl:xss text="{/input}"/>
</mvc:View>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ edges
| webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/controller/app.controller.js:11:26:11:45 | new JSONModel(oData) |
| webapp/view/app.view.xml:8:5:8:38 | text={/input} | webapp/controller/app.controller.js:9:17:9:27 | input: null |
#select
| webapp/control/xss.js:14:28:14:45 | oControl.getText() | webapp/control/xss.js:7:19:7:36 | { type: "string" } | webapp/control/xss.js:14:28:14:45 | oControl.getText() | XSS vulnerability due to $@. | webapp/control/xss.js:7:19:7:36 | { type: "string" } | user-provided value |
| webapp/control/xss.js:14:28:14:45 | oControl.getText() | webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/control/xss.js:14:28:14:45 | oControl.getText() | XSS vulnerability due to $@. | webapp/view/app.view.xml:5:5:7:28 | value={/input} | user-provided value |
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ edges
| webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/controller/app.controller.js:11:26:11:45 | new JSONModel(oData) |
| webapp/view/app.view.xml:8:5:8:38 | text={/input} | webapp/controller/app.controller.js:9:17:9:27 | input: null |
#select
| webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | webapp/control/xssBase.js:5:15:5:32 | { type: "string" } | webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | XSS vulnerability due to $@. | webapp/control/xssBase.js:5:15:5:32 | { type: "string" } | user-provided value |
| webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | XSS vulnerability due to $@. | webapp/view/app.view.xml:5:5:7:28 | value={/input} | user-provided value |
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ edges
| webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/controller/app.controller.js:11:26:11:45 | new JSONModel(oData) |
| webapp/view/app.view.xml:8:5:8:38 | text={/input} | webapp/controller/app.controller.js:9:17:9:27 | input: null |
#select
| webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | webapp/control/xss.js:7:23:7:40 | { type: "string" } | webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | XSS vulnerability due to $@. | webapp/control/xss.js:7:23:7:40 | { type: "string" } | user-provided value |
| webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | webapp/view/app.view.xml:5:5:7:28 | value={/input} | webapp/control/xssRenderer.js:8:28:8:45 | oControl.getText() | XSS vulnerability due to $@. | webapp/view/app.view.xml:5:5:7:28 | value={/input} | user-provided value |
Loading
Loading