Skip to content

Commit 271b2f3

Browse files
committed
JS: add RemoteFlowSource.isThirdPartyControllable()
Use it in ReflectedXSS and ServerSideURrlRedirect
1 parent b35f450 commit 271b2f3

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

javascript/ql/src/semmle/javascript/frameworks/HTTP.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,13 @@ module HTTP {
399399
* Note that this predicate is functional.
400400
*/
401401
abstract string getKind();
402+
403+
override predicate isThirdPartyControllable() {
404+
exists (string kind | kind = getKind() |
405+
kind = "parameter" or
406+
kind = "url" or
407+
kind = "body")
408+
}
402409
}
403410

404411
/**

javascript/ql/src/semmle/javascript/security/dataflow/ReflectedXss.qll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ module ReflectedXss {
4646
/** A source of remote user input, considered as a flow source for reflected XSS. */
4747
class RemoteFlowSourceAsSource extends Source {
4848
RemoteFlowSourceAsSource() {
49-
this instanceof RemoteFlowSource and
50-
// cookies cannot be controlled by a third-party attacker, and hence are
51-
// not relevant for reflected XSS
52-
not this.(RemoteFlowSource).getSourceType() = "Server request cookie"
49+
this.(RemoteFlowSource).isThirdPartyControllable()
5350
}
5451
}
5552

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,19 @@ import semmle.javascript.security.dataflow.DOM
1010
abstract class RemoteFlowSource extends DataFlow::Node {
1111
/** Gets a string that describes the type of this remote flow source. */
1212
abstract string getSourceType();
13-
}
1413

14+
/**
15+
* Holds if this flow source comes from an incoming request, and this part of the
16+
* request can be controlled by a third party, that is, an actor other than the one
17+
* sending the request.
18+
*
19+
* Any web site can redirect the visitor's browser to any other domain, and in doing so control
20+
* the entire URL and POST body. In this scenario, these values are technically sent by the
21+
* user's browser, but the user is not in direct control of these values, so they are considered
22+
* third-party controllable.
23+
*/
24+
predicate isThirdPartyControllable() { none() }
25+
}
1526

1627
/**
1728
* An access to `document.cookie`, viewed as a source of remote user input.

javascript/ql/src/semmle/javascript/security/dataflow/ServerSideUrlRedirect.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ module ServerSideUrlRedirect {
9090

9191
}
9292

93-
/** A source of remote user input, considered as a flow source for URL redirects. */
93+
/** A source of third-party user input, considered as a flow source for URL redirects. */
9494
class RemoteFlowSourceAsSource extends Source {
95-
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
95+
RemoteFlowSourceAsSource() {
96+
this.(RemoteFlowSource).isThirdPartyControllable()
97+
}
9698
}
9799

98100
/**

0 commit comments

Comments
 (0)