@@ -33,7 +33,14 @@ class ConstantStateFlowConf extends DataFlow::Configuration {
33
33
}
34
34
35
35
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
+ )
37
44
}
38
45
39
46
override predicate isSink ( DataFlow:: Node sink ) { isSink ( sink , _) }
@@ -50,6 +57,21 @@ predicate isUrlTaintingConfigStep(DataFlow::Node pred, DataFlow::Node succ) {
50
57
)
51
58
}
52
59
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
+
53
75
/**
54
76
* A flow of a URL indicating the OAuth redirect doesn't point to a publicly
55
77
* accessible address, to the receiver of an `AuthCodeURL` call.
@@ -61,15 +83,14 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration {
61
83
PrivateUrlFlowsToAuthCodeUrlCall ( ) { this = "PrivateUrlFlowsToConfig" }
62
84
63
85
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
+ )
73
94
}
74
95
75
96
override predicate isAdditionalFlowStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
0 commit comments