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