Skip to content

Commit 8233039

Browse files
author
Stephan Brandauer
committed
CWE-830 add support for setting attributes via setAttribute method
1 parent d80cd1a commit 8233039

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

javascript/ql/src/Security/CWE-830/FunctionalityFromUntrustedSource.ql

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,22 @@ module DynamicCreation {
9090
call.getArgument(0).getStringValue().toLowerCase() = name
9191
}
9292

93+
DataFlow::Node getAttributeAssignmentRhs(DataFlow::CallNode createCall, string name) {
94+
result = createCall.getAPropertyWrite(name).getRhs()
95+
or
96+
exists(DataFlow::InvokeNode inv | inv = createCall.getAMemberInvocation("setAttribute") |
97+
inv.getArgument(0).getStringValue() = name and
98+
result = inv.getArgument(1)
99+
)
100+
}
101+
93102
/**
94103
* Holds if `createCall` creates a `<script ../>` element which never
95104
* has its `integrity` attribute set locally.
96105
*/
97106
predicate isCreateScriptNodeWoIntegrityCheck(DataFlow::CallNode createCall) {
98107
isCreateElementNode(createCall, "script") and
99-
not exists(createCall.getAPropertyWrite("integrity"))
108+
not exists(getAttributeAssignmentRhs(createCall, "integrity"))
100109
}
101110

102111
DataFlow::Node urlTrackedFromUnsafeSourceLiteral(DataFlow::TypeTracker t) {
@@ -126,15 +135,17 @@ module DynamicCreation {
126135
result = urlTrackedFromUnsafeSourceLiteral(DataFlow::TypeTracker::end())
127136
}
128137

138+
/** Holds if `sink` is assigned to the attribute `name` of any HTML element. */
129139
predicate isAssignedToSrcAttribute(string name, DataFlow::Node sink) {
130140
exists(DataFlow::CallNode createElementCall |
131-
name = "script" and
132-
isCreateScriptNodeWoIntegrityCheck(createElementCall) and
133-
sink = createElementCall.getAPropertyWrite("src").getRhs()
134-
or
135-
name = "iframe" and
136-
isCreateElementNode(createElementCall, "iframe") and
137-
sink = createElementCall.getAPropertyWrite("src").getRhs()
141+
sink = getAttributeAssignmentRhs(createElementCall, "src") and
142+
(
143+
name = "script" and
144+
isCreateScriptNodeWoIntegrityCheck(createElementCall)
145+
or
146+
name = "iframe" and
147+
isCreateElementNode(createElementCall, "iframe")
148+
)
138149
)
139150
}
140151

@@ -143,8 +154,8 @@ module DynamicCreation {
143154

144155
IframeOrScriptSrcAssignment() {
145156
exists(DataFlow::Node n | n.asExpr() = this |
146-
DynamicCreation::isAssignedToSrcAttribute(name, n) and
147-
n = DynamicCreation::urlTrackedFromUnsafeSourceLiteral()
157+
isAssignedToSrcAttribute(name, n) and
158+
n = urlTrackedFromUnsafeSourceLiteral()
148159
)
149160
}
150161

javascript/ql/test/query-tests/Security/CWE-830/DynamicCreationOfUntrustedSourceUse.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
var ifrm3 = document.createElement('iframe');
3434
ifrm3.src = getUrl('v123');
3535

36+
// NOT OK (assignment of bad URL using setAttribute)
37+
var ifrm4 = document.createElement('iframe');
38+
ifrm4.setAttribute('src', 'http://www.example.local/page.html');
39+
40+
// OK (bad URL, but the attribute is not `src`)
41+
var ifrm5 = document.createElement('iframe');
42+
ifrm5.setAttribute('data-src', 'http://www.example.local/page.html');
3643
})();
3744
</script>
3845
</head>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
| DynamicCreationOfUntrustedSourceUse.html:19:28:19:129 | ('https ... /ga.js' | HTML script element loaded using unencrypted connection. |
22
| DynamicCreationOfUntrustedSourceUse.html:23:26:23:50 | 'http:/ ... e.com/' | HTML iframe element loaded using unencrypted connection. |
33
| DynamicCreationOfUntrustedSourceUse.html:34:27:34:40 | getUrl('v123') | HTML iframe element loaded using unencrypted connection. |
4+
| DynamicCreationOfUntrustedSourceUse.html:38:41:38:76 | 'http:/ ... e.html' | HTML iframe element loaded using unencrypted connection. |
45
| StaticCreationOfUntrustedSourceUse.html:6:9:6:56 | <script>...</> | HTML script element loaded using unencrypted connection. |
56
| StaticCreationOfUntrustedSourceUse.html:9:9:9:58 | <iframe>...</> | HTML iframe element loaded using unencrypted connection. |
67
| StaticCreationOfUntrustedSourceUse.html:21:9:21:155 | <script>...</> | Script loaded from content delivery network with no integrity check. |

0 commit comments

Comments
 (0)