Skip to content

Commit fc5c389

Browse files
committed
JS: Add browser source kinds
1 parent 99de5d4 commit fc5c389

4 files changed

Lines changed: 49 additions & 12 deletions

File tree

javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ private class RemoteFlowSourceFromMaD extends RemoteFlowSource {
3535
override string getSourceType() { result = "Remote flow" }
3636
}
3737

38+
private class ClientSideRemoteFlowSourceFromMaD extends ClientSideRemoteFlowSource {
39+
private ClientSideRemoteFlowKind kind;
40+
41+
ClientSideRemoteFlowSourceFromMaD() { ModelOutput::sourceNode(this, kind) }
42+
43+
override ClientSideRemoteFlowKind getKind() { result = kind }
44+
45+
override string getSourceType() {
46+
result = "Source node (" + this.getThreatModel() + ") [from data-extension]"
47+
}
48+
}
49+
3850
/**
3951
* A threat-model flow source originating from a data extension.
4052
*/

javascript/ql/lib/semmle/javascript/security/dataflow/RemoteFlowSources.qll

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ private module Cached {
3030
*/
3131
cached
3232
abstract class ClientSideRemoteFlowSource extends RemoteFlowSource {
33+
cached
34+
override string getThreatModel() { result = this.getKind() }
35+
3336
/** Gets a string indicating what part of the browser environment this was derived from. */
3437
cached
3538
abstract ClientSideRemoteFlowKind getKind();
@@ -43,35 +46,41 @@ import Cached
4346

4447
/**
4548
* A type of remote flow source that is specific to the browser environment.
49+
*
50+
* The underlying string also corresponds to a source kind and threat model kind.
4651
*/
4752
class ClientSideRemoteFlowKind extends string {
4853
ClientSideRemoteFlowKind() {
49-
this = ["query", "fragment", "path", "url", "name", "message-event"]
54+
this =
55+
[
56+
"browser-url-query", "browser-url-fragment", "browser-url-path", "browser-url",
57+
"browser-window-name", "browser-message-event"
58+
]
5059
}
5160

5261
/**
53-
* Holds if this is the `query` kind, describing sources derived from the query parameters of the browser URL,
62+
* Holds if this is the `browser-url-query` kind, describing sources derived from the query parameters of the browser URL,
5463
* such as `location.search`.
5564
*/
56-
predicate isQuery() { this = "query" }
65+
predicate isQuery() { this = "browser-url-query" }
5766

5867
/**
59-
* Holds if this is the `frgament` kind, describing sources derived from the fragment part of the browser URL,
68+
* Holds if this is the `browser-url-fragment` kind, describing sources derived from the fragment part of the browser URL,
6069
* such as `location.hash`.
6170
*/
62-
predicate isFragment() { this = "fragment" }
71+
predicate isFragment() { this = "browser-url-fragment" }
6372

6473
/**
65-
* Holds if this is the `path` kind, describing sources derived from the pathname of the browser URL,
74+
* Holds if this is the `browser-url-path` kind, describing sources derived from the pathname of the browser URL,
6675
* such as `location.pathname`.
6776
*/
68-
predicate isPath() { this = "path" }
77+
predicate isPath() { this = "browser-url-path" }
6978

7079
/**
71-
* Holds if this is the `url` kind, describing sources derived from the browser URL,
80+
* Holds if this is the `browser-url` kind, describing sources derived from the browser URL,
7281
* where the untrusted part of the URL is prefixed by trusted data, such as the scheme and hostname.
7382
*/
74-
predicate isUrl() { this = "url" }
83+
predicate isUrl() { this = "browser-url" }
7584

7685
/** Holds if this is the `query` or `fragment` kind. */
7786
predicate isQueryOrFragment() { this.isQuery() or this.isFragment() }
@@ -83,13 +92,13 @@ class ClientSideRemoteFlowKind extends string {
8392
predicate isPathOrUrl() { this.isPath() or this.isUrl() }
8493

8594
/** Holds if this is the `name` kind, describing sources derived from the window name, such as `window.name`. */
86-
predicate isWindowName() { this = "name" }
95+
predicate isWindowName() { this = "browser-window-name" }
8796

8897
/**
89-
* Holds if this is the `message-event` kind, describing sources derived from cross-window message passing,
98+
* Holds if this is the `browser-message-event` kind, describing sources derived from cross-window message passing,
9099
* such as `event` in `window.onmessage = event => {...}`.
91100
*/
92-
predicate isMessageEvent() { this = "message-event" }
101+
predicate isMessageEvent() { this = "browser-message-event" }
93102
}
94103

95104
/**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
| browser |
2+
| browser-message-event |
3+
| browser-url |
4+
| browser-url-fragment |
5+
| browser-url-path |
6+
| browser-url-query |
7+
| browser-window-name |
18
| default |
29
| remote |
310
| request |

shared/threat-models/ext/threat-model-grouping.model.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ extensions:
2323
- ["android-external-storage-dir", "android"]
2424
- ["contentprovider", "android"]
2525

26+
# Browser sources
27+
- ["browser", "remote"]
28+
- ["browser-window-name", "browser"]
29+
- ["browser-message-event", "browser"]
30+
- ["browser-url", "browser"]
31+
- ["browser-url-query", "browser-url"]
32+
- ["browser-url-path", "browser-url"]
33+
- ["browser-url-fragment", "browser-url"]
34+
2635
# Threat models that are not grouped with any other threat models.
2736
# (Note that all threat models are a child of "all" implicitly, and we
2837
# make it explicit here just to make sure all threat models are listed.)

0 commit comments

Comments
 (0)