Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit b487799

Browse files
committed
Oauth2 state query: avoid duplicate paths by excluding variable references as sources
1 parent 6fea8ab commit b487799

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

ql/src/Security/CWE-352/ConstantOauth2State.ql

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ class ConstantStateFlowConf extends DataFlow::Configuration {
3333
}
3434

3535
override predicate isSource(DataFlow::Node source) {
36-
source.isConst() and not DataFlow::isReturnedWithError(source)
36+
source.isConst() and
37+
not DataFlow::isReturnedWithError(source) and
38+
// Avoid duplicate paths by not considering reads from constants as sources themselves:
39+
(
40+
source.asExpr() instanceof StringLit
41+
or
42+
source.asExpr() instanceof AddExpr
43+
)
3744
}
3845

3946
override predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
@@ -50,6 +57,21 @@ predicate isUrlTaintingConfigStep(DataFlow::Node pred, DataFlow::Node succ) {
5057
)
5158
}
5259

60+
/**
61+
* Gets a URL or pseudo-URL that suggests an out-of-band OAuth2 flow or use of a transient
62+
* local listener to receive an OAuth2 redirect.
63+
*/
64+
bindingset[result]
65+
string getAnOobOauth2Url() {
66+
// The following are pseudo-URLs seen in the wild to indicate the authenticating site
67+
// should display a code for the user to manually convey, rather than directing:
68+
result in ["urn:ietf:wg:oauth:2.0:oob", "urn:ietf:wg:oauth:2.0:oob:auto", "oob", "code"] or
69+
// Alternatively some non-web tools will create a temporary local webserver to handle the
70+
// OAuth2 redirect:
71+
result.matches("%://localhost%") or
72+
result.matches("%://127.0.0.1%")
73+
}
74+
5375
/**
5476
* A flow of a URL indicating the OAuth redirect doesn't point to a publicly
5577
* accessible address, to the receiver of an `AuthCodeURL` call.
@@ -61,15 +83,14 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration {
6183
PrivateUrlFlowsToAuthCodeUrlCall() { this = "PrivateUrlFlowsToConfig" }
6284

6385
override predicate isSource(DataFlow::Node source) {
64-
// The following are all common ways to indicate out-of-band OAuth2 flow, in which case
65-
// the authenticating party does not redirect but presents a code for the user to copy
66-
// instead.
67-
source.getStringValue() in ["urn:ietf:wg:oauth:2.0:oob", "urn:ietf:wg:oauth:2.0:oob:auto",
68-
"oob", "code"] or
69-
// Alternatively some non-web tools will create a temporary local webserver to handle the
70-
// OAuth2 redirect:
71-
source.getStringValue().matches("%://localhost%") or
72-
source.getStringValue().matches("%://127.0.0.1%")
86+
source.getStringValue() = getAnOobOauth2Url() and
87+
// Avoid duplicate paths by excluding constant variable references from
88+
// themselves being sources:
89+
(
90+
source.asExpr() instanceof StringLit
91+
or
92+
source.asExpr() instanceof AddExpr
93+
)
7394
}
7495

7596
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {

0 commit comments

Comments
 (0)