JS: Add clipboard data as a source for `js/xss` by erik-krogh · Pull Request #6584 · github/codeql · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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: 2 additions & 0 deletions javascript/change-notes/2021-09-01-clipboard-data.md
1 change: 1 addition & 0 deletions javascript/ql/lib/javascript.qll
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import semmle.javascript.frameworks.ComposedFunctions
import semmle.javascript.frameworks.Classnames
import semmle.javascript.frameworks.ClassValidator
import semmle.javascript.frameworks.ClientRequests
import semmle.javascript.frameworks.Clipboard
import semmle.javascript.frameworks.ClosureLibrary
import semmle.javascript.frameworks.CookieLibraries
import semmle.javascript.frameworks.Credentials
Expand Down
2 changes: 2 additions & 0 deletions javascript/ql/lib/semmle/javascript/DOM.qll
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ module DOM {
result = domValueRef(DataFlow::TypeTracker::end())
or
result.hasUnderlyingType("Element")
or
result.hasUnderlyingType(any(string s | s.matches("HTML%Element")))
}

module LocationSource {
Expand Down
63 changes: 63 additions & 0 deletions javascript/ql/lib/semmle/javascript/frameworks/Clipboard.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Provides predicates for reasoning about clipboard data.
*/

import javascript

/**
* Gets a jQuery "paste" event.
* E.g. `e` in `$("#foo").on("paste", function(e) { ... })`.
*/
private DataFlow::SourceNode jQueryPasteEvent(DataFlow::TypeTracker t) {
t.start() and
exists(DataFlow::CallNode call |
call = JQuery::objectRef().getAMethodCall(["bind", "on", "live", "one", "delegate"]) and
call.getArgument(0).mayHaveStringValue("paste")
|
result = call.getCallback(call.getNumArgument() - 1).getParameter(0)
)
or
exists(DataFlow::TypeTracker t2 | result = jQueryPasteEvent(t2).track(t2, t))
}

/**
* Gets a DOM "paste" event.
* E.g. `e` in `document.addEventListener("paste", e => { ... })`.
*/
private DataFlow::SourceNode pasteEvent(DataFlow::TypeTracker t) {
t.start() and
exists(DataFlow::CallNode call | call = DOM::domValueRef().getAMemberCall("addEventListener") |
call.getArgument(0).mayHaveStringValue("paste") and
result = call.getCallback(1).getParameter(0)
)
or
t.start() and
result = jQueryPasteEvent(DataFlow::TypeTracker::end()).getAPropertyRead("originalEvent")
or
exists(DataFlow::TypeTracker t2 | result = pasteEvent(t2).track(t2, t))
}

/**
* Gets a reference to the clipboardData DataTransfer object.
* https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData
*/
private DataFlow::SourceNode clipboardDataTransferSource(DataFlow::TypeTracker t) {
t.start() and
exists(DataFlow::PropRead read | read = result |
read.getPropertyName() = "clipboardData" and
read.getBase().getALocalSource() = pasteEvent(DataFlow::TypeTracker::end())
)
or
exists(DataFlow::TypeTracker t2 | result = clipboardDataTransferSource(t2).track(t2, t))
}

/**
* A reference to data from the clipboard. Seen as a source for DOM-based XSS.
*/
private class ClipboardSource extends RemoteFlowSource {
ClipboardSource() {
this = clipboardDataTransferSource(DataFlow::TypeTracker::end()).getAMethodCall("getData")
}

override string getSourceType() { result = "Clipboard data" }
}

This file was deleted.

78 changes: 0 additions & 78 deletions javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.ql

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ nodes
| classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name |
| classnames.js:15:52:15:62 | window.name |
| clipboard.ts:8:11:8:51 | html |
| clipboard.ts:8:18:8:51 | clipboa ... /html') |
| clipboard.ts:8:18:8:51 | clipboa ... /html') |
| clipboard.ts:15:25:15:28 | html |
| clipboard.ts:15:25:15:28 | html |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') |
| d3.js:4:12:4:22 | window.name |
| d3.js:4:12:4:22 | window.name |
| d3.js:11:15:11:24 | getTaint() |
Expand Down Expand Up @@ -857,6 +871,13 @@ edges
| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `<span ... <span>` |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html |
| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html |
| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html |
| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') |
| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() |
| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() |
| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() |
Expand Down Expand Up @@ -1514,6 +1535,10 @@ edges
| classnames.js:11:31:11:79 | `<span ... <span>` | classnames.js:10:45:10:55 | window.name | classnames.js:11:31:11:79 | `<span ... <span>` | Cross-site scripting vulnerability due to $@. | classnames.js:10:45:10:55 | window.name | user-provided value |
| classnames.js:13:31:13:83 | `<span ... <span>` | classnames.js:13:57:13:67 | window.name | classnames.js:13:31:13:83 | `<span ... <span>` | Cross-site scripting vulnerability due to $@. | classnames.js:13:57:13:67 | window.name | user-provided value |
| classnames.js:15:31:15:78 | `<span ... <span>` | classnames.js:15:52:15:62 | window.name | classnames.js:15:31:15:78 | `<span ... <span>` | Cross-site scripting vulnerability due to $@. | classnames.js:15:52:15:62 | window.name | user-provided value |
| clipboard.ts:15:25:15:28 | html | clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:15:25:15:28 | html | Cross-site scripting vulnerability due to $@. | clipboard.ts:8:18:8:51 | clipboa ... /html') | user-provided value |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:24:23:24:58 | e.clipb ... /html') | user-provided value |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:29:19:29:54 | e.clipb ... /html') | user-provided value |
| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:33:19:33:68 | e.origi ... /html') | user-provided value |
| d3.js:11:15:11:24 | getTaint() | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | Cross-site scripting vulnerability due to $@. | d3.js:4:12:4:22 | window.name | user-provided value |
| d3.js:12:20:12:29 | getTaint() | d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | Cross-site scripting vulnerability due to $@. | d3.js:4:12:4:22 | window.name | user-provided value |
| d3.js:14:20:14:29 | getTaint() | d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | Cross-site scripting vulnerability due to $@. | d3.js:4:12:4:22 | window.name | user-provided value |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ nodes
| classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name |
| classnames.js:15:52:15:62 | window.name |
| clipboard.ts:8:11:8:51 | html |
| clipboard.ts:8:18:8:51 | clipboa ... /html') |
| clipboard.ts:8:18:8:51 | clipboa ... /html') |
| clipboard.ts:15:25:15:28 | html |
| clipboard.ts:15:25:15:28 | html |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') |
| d3.js:4:12:4:22 | window.name |
| d3.js:4:12:4:22 | window.name |
| d3.js:11:15:11:24 | getTaint() |
Expand Down Expand Up @@ -875,6 +889,13 @@ edges
| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `<span ... <span>` |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html |
| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html |
| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html |
| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html |
| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') |
| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') |
| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') |
| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() |
| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() |
| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() |
Expand Down