1
+ const express = require ( 'express' ) ;
2
+ const app = express ( ) ;
3
+
4
+ app . use ( express . json ( ) ) ;
5
+
6
+ app . get ( '/direct-ternary-operator' , function ( req , res ) {
7
+ let taintedURL = req . params . url
8
+
9
+ let v = req . params . url ? req . params . url == "someURL" : false
10
+ if ( v ) {
11
+ req_frontend_restclient . get ( req . params . url ) // OK
12
+ }
13
+
14
+ let v1 = taintedURL ? taintedURL == "someURL" : false
15
+ if ( v1 ) {
16
+ req_frontend_restclient . get ( taintedURL ) // OK
17
+ }
18
+
19
+ let v2 = taintedURL ? valid ( taintedURL ) : false
20
+ if ( v2 ) {
21
+ req_frontend_restclient . get ( taintedURL ) // OK
22
+ }
23
+
24
+ let v3 = req . params . url ? valid ( req . params . url ) : false
25
+ if ( v3 ) {
26
+ req_frontend_restclient . get ( req . params . url ) // OK
27
+ }
28
+
29
+ let v4 = req . params . url == undefined ? false : valid ( req . params . url )
30
+ if ( v4 ) {
31
+ req_frontend_restclient . get ( req . params . url ) // OK
32
+ }
33
+
34
+ let v5 = req . params . url == undefined ? true : valid ( req . params . url )
35
+ if ( v5 ) {
36
+ req_frontend_restclient . get ( req . params . url ) // SSRF
37
+ }
38
+
39
+ let v6 = req . params . url ? valid ( req . params . url ) : true
40
+ if ( v6 ) {
41
+ req_frontend_restclient . get ( req . params . url ) // SSRF
42
+ }
43
+
44
+ let f = false
45
+ let v7 = req . params . url ? valid ( req . params . url ) : true
46
+ if ( v7 ) {
47
+ req_frontend_restclient . get ( req . params . url ) // SSRF
48
+ }
49
+
50
+ let v8 = req . params . url == undefined ? false : valid ( req . params . url )
51
+ if ( ! v8 ) {
52
+ return
53
+ }
54
+ req_frontend_restclient . get ( req . params . url ) // OK
55
+ } )
56
+
57
+ app . get ( '/functions' , function ( req , res ) {
58
+ let taintedURL = req . params . url
59
+
60
+ if ( valid2 ( taintedURL ) ) {
61
+ req_frontend_restclient . get ( taintedURL ) // OK
62
+ }
63
+
64
+ if ( ! invalid ( taintedURL ) ) {
65
+ req_frontend_restclient . get ( taintedURL ) // False positive
66
+ }
67
+
68
+ if ( valid2 ( req . params . url ) ) {
69
+ req_frontend_restclient . get ( req . params . url ) // OK
70
+ }
71
+
72
+ if ( ! assertAlphanumeric ( req . params . url ) ) {
73
+ return
74
+ }
75
+ req_frontend_restclient . get ( req . params . url ) ; // OK
76
+ } )
77
+
78
+ app . get ( '/normal-use-of-ternary-operator' , function ( req , res ) {
79
+ let taintedURL = req . params . url
80
+
81
+ let url = valid ( req . params . url ) ? req . params . url : undefined
82
+ req_frontend_restclient . get ( url ) // OK
83
+
84
+ let url = valid ( taintedURL ) ? taintedURL : undefined
85
+ req_frontend_restclient . get ( url ) // OK
86
+
87
+ let url4 = req . params . url . match ( / ^ [ \w . - ] + $ / ) ? req . params . url : undefined
88
+ req_frontend_restclient . get ( url4 ) // OK
89
+ } )
90
+
91
+ app . get ( '/throw-errors' , function ( req , res ) {
92
+ req_frontend_restclient . get ( valid3 ( req . params . url ) ) // False positive
93
+
94
+ req_frontend_restclient . get ( assertOther ( req . params . url ) ) ; // False positive
95
+
96
+ req_frontend_restclient . get ( assertOther2 ( req . params . url ) ) ; // False positive
97
+ } ) ;
98
+
99
+ app . get ( '/bad-endpoint' , function ( req , res ) {
100
+ req_frontend_restclient . get ( req . params . url ) ; // SSRF
101
+
102
+ const valid = req . params . url ? req . params . url == "someURL" : false
103
+ if ( ! valid ) {
104
+ throw new Error ( `Invalid parameter: "${ req . params . url } ", must be alphanumeric` ) ;
105
+ }
106
+ req_frontend_restclient . get ( req . params . url ) ; // OK
107
+ } )
108
+
109
+
110
+ app . get ( '/bad-endpoint-variable' , function ( req , res ) {
111
+ let taintedURL = req . params . url
112
+ req_frontend_restclient . get ( taintedURL ) ; // SSRF
113
+
114
+ const valid = taintedURL ? taintedURL == "someURL" : false
115
+ if ( ! valid ) {
116
+ return
117
+ }
118
+ req_frontend_restclient . get ( taintedURL ) ; // False positive
119
+ } )
120
+
121
+ app . get ( '/not-invalid' , function ( req , res ) {
122
+ const invalidParam = req . params . url ? ! Number . isInteger ( req . params . url ) : false
123
+ if ( invalidParam ) {
124
+ return
125
+ }
126
+ req_frontend_restclient . get ( req . params . url ) ; // False positive
127
+ } )
128
+
129
+
130
+ app . get ( '/bad-endpoint-2' , function ( req , res ) {
131
+ other ( req . params . url )
132
+ } )
133
+
134
+ function other ( taintedURL ) {
135
+ req_frontend_restclient . get ( taintedURL ) ; // SSRF
136
+
137
+ const valid = taintedURL ? taintedURL == "someURL" : false
138
+ if ( ! valid ) {
139
+ return
140
+ }
141
+ req_frontend_restclient . get ( taintedURL ) ; // False positive
142
+ }
143
+
144
+ function assertAlphanumeric ( value ) {
145
+ return value ? value . match ( / ^ [ \w . - ] + $ / ) : false ;
146
+ }
147
+
148
+ function assertOther ( value ) {
149
+ const valid = value ? ! ! value . match ( / ^ [ \w . - ] + $ / ) : false ;
150
+ if ( ! valid ) {
151
+ throw new Error ( `Invalid parameter: "${ value } ", must be alphanumeric` ) ;
152
+ }
153
+ return value ;
154
+ }
155
+
156
+ function assertOther2 ( value ) {
157
+ const valid = value ? value . match ( / ^ [ \w . - ] + $ / ) : false ;
158
+ if ( ! valid ) {
159
+ throw new Error ( `Invalid parameter: "${ value } ", must be alphanumeric` ) ;
160
+ }
161
+ return value ;
162
+ }
163
+
164
+ function invalid ( value ) {
165
+ return value ? ! Number . isInteger ( value ) : true
166
+ }
167
+
168
+ function valid ( value ) {
169
+ return value . match ( / ^ [ \w . - ] + $ / )
170
+ }
171
+
172
+ function valid2 ( value ) {
173
+ return value ? value == "someURL" : false
174
+ }
175
+
176
+ function valid3 ( value ) {
177
+ const valid = value ? value == "someURL" : false
178
+ if ( ! valid ) {
179
+ throw new Error ( `Invalid parameter: "${ value } ", must be alphanumeric` ) ;
180
+ }
181
+ return value ;
182
+ }
0 commit comments