1- from flask import request
1+ from flask import request # $ Source
22
33import requests
44import re
@@ -7,20 +7,24 @@ def full_ssrf():
77 user_input = request .args ['untrusted_input' ]
88 query_val = request .args ['query_val' ]
99
10- requests .get (user_input ) # NOT OK -- user has full control
10+ # NOT OK -- user has full control
11+ requests .get (user_input ) # $ Alert[py/full-ssrf]
1112
1213 url = "https://" + user_input
13- requests .get (url ) # NOT OK -- user has full control
14+ # NOT OK -- user has full control
15+ requests .get (url ) # $ Alert[py/full-ssrf]
1416
1517 # although the path `/foo` is added here, this can be circumvented such that the
1618 # final URL is `https://evil.com/#/foo" -- since the fragment (#) is not sent to the
1719 # server.
1820 url = "https://" + user_input + "/foo"
19- requests .get (url ) # NOT OK -- user has full control
21+ # NOT OK -- user has full control
22+ requests .get (url ) # $ Alert[py/full-ssrf]
2023
2124 # this might seem like a dummy test, but it serves to check how our sanitizers work.
2225 url = "https://" + user_input + "/foo?key=" + query_val
23- requests .get (url ) # NOT OK -- user has full control
26+ # NOT OK -- user has full control
27+ requests .get (url ) # $ Alert[py/full-ssrf]
2428
2529# taint-steps are added as `fromNode -> toNode`, but when adding a sanitizer it's
2630# currently only possible to so on either `fromNode` or `toNode` (either all edges in
@@ -39,72 +43,87 @@ def full_ssrf_format():
3943
4044 # using .format
4145 url = "https://{}" .format (user_input )
42- requests .get (url ) # NOT OK -- user has full control
46+ # NOT OK -- user has full control
47+ requests .get (url ) # $ Alert[py/full-ssrf]
4348
4449 url = "https://{}/foo" .format (user_input )
45- requests .get (url ) # NOT OK -- user has full control
50+ # NOT OK -- user has full control
51+ requests .get (url ) # $ Alert[py/full-ssrf]
4652
4753 url = "https://{}/foo?key={}" .format (user_input , query_val )
48- requests .get (url ) # NOT OK -- user has full control
54+ # NOT OK -- user has full control
55+ requests .get (url ) # $ Alert[py/full-ssrf]
4956
5057 url = "https://{x}" .format (x = user_input )
51- requests .get (url ) # NOT OK -- user has full control
58+ # NOT OK -- user has full control
59+ requests .get (url ) # $ Alert[py/full-ssrf]
5260
5361 url = "https://{1}" .format (0 , user_input )
54- requests .get (url ) # NOT OK -- user has full control
62+ # NOT OK -- user has full control
63+ requests .get (url ) # $ Alert[py/full-ssrf]
5564
5665def full_ssrf_percent_format ():
5766 user_input = request .args ['untrusted_input' ]
5867 query_val = request .args ['query_val' ]
5968
6069 # using %-formatting
6170 url = "https://%s" % user_input
62- requests .get (url ) # NOT OK -- user has full control
71+ # NOT OK -- user has full control
72+ requests .get (url ) # $ Alert[py/full-ssrf]
6373
6474 url = "https://%s/foo" % user_input
65- requests .get (url ) # NOT OK -- user has full control
75+ # NOT OK -- user has full control
76+ requests .get (url ) # $ Alert[py/full-ssrf]
6677
6778 url = "https://%s/foo/key=%s" % (user_input , query_val )
68- requests .get (url ) # NOT OK -- user has full control
79+ # NOT OK -- user has full and partial control
80+ requests .get (url ) # $ Alert[py/partial-ssrf] $ MISSING: Alert[py/full-ssrf]
6981
7082def full_ssrf_f_strings ():
7183 user_input = request .args ['untrusted_input' ]
7284 query_val = request .args ['query_val' ]
7385
7486 # using f-strings
7587 url = f"https://{ user_input } "
76- requests .get (url ) # NOT OK -- user has full control
88+ # NOT OK -- user has full control
89+ requests .get (url ) # $ Alert[py/full-ssrf]
7790
7891 url = f"https://{ user_input } /foo"
79- requests .get (url ) # NOT OK -- user has full control
92+ # NOT OK -- user has full control
93+ requests .get (url ) # $ Alert[py/full-ssrf]
8094
8195 url = f"https://{ user_input } /foo?key={ query_val } "
82- requests .get (url ) # NOT OK -- user has full control
96+ # NOT OK -- user has full control
97+ requests .get (url ) # $ Alert[py/full-ssrf]
8398
8499
85100def partial_ssrf_1 ():
86101 user_input = request .args ['untrusted_input' ]
87102
88103 url = "https://example.com/foo?" + user_input
89- requests .get (url ) # NOT OK -- user controls query parameters
104+ # NOT OK -- user controls query parameters
105+ requests .get (url ) # $ Alert[py/partial-ssrf]
90106
91107def partial_ssrf_2 ():
92108 user_input = request .args ['untrusted_input' ]
93109
94110 url = "https://example.com/" + user_input
95- requests .get (url ) # NOT OK -- user controls path
111+ # NOT OK -- user controls path
112+ requests .get (url ) # $ Alert[py/partial-ssrf]
96113
97114def partial_ssrf_3 ():
98115 user_input = request .args ['untrusted_input' ]
99116
100117 url = "https://example.com/" + user_input
101- requests .get (url ) # NOT OK -- user controls path
118+ # NOT OK -- user controls path
119+ requests .get (url ) # $ Alert[py/partial-ssrf]
102120
103121def partial_ssrf_4 ():
104122 user_input = request .args ['untrusted_input' ]
105123
106124 url = "https://example.com/foo#{}" .format (user_input )
107- requests .get (url ) # NOT OK -- user contollred fragment
125+ # NOT OK -- user controlled fragment
126+ requests .get (url ) # $ Alert[py/partial-ssrf]
108127
109128def partial_ssrf_5 ():
110129 user_input = request .args ['untrusted_input' ]
@@ -113,20 +132,22 @@ def partial_ssrf_5():
113132 # controlled
114133
115134 url = "https://example.com/foo#%s" % user_input
116- requests .get (url ) # NOT OK -- user contollred fragment
135+ # NOT OK -- user controlled fragment
136+ requests .get (url ) # $ Alert[py/partial-ssrf]
117137
118138def partial_ssrf_6 ():
119139 user_input = request .args ['untrusted_input' ]
120140
121141 url = f"https://example.com/foo#{ user_input } "
122- requests .get (url ) # NOT OK -- user only controlled fragment
142+ # NOT OK -- user only controlled fragment
143+ requests .get (url ) # $ Alert[py/partial-ssrf]
123144
124145def partial_ssrf_7 ():
125146 user_input = request .args ['untrusted_input' ]
126147
127148 if user_input .isalnum ():
128149 url = f"https://example.com/foo#{ user_input } "
129- requests .get (url ) # OK - user input can only contain alphanumerical characters
150+ requests .get (url ) # OK - user input can only contain alphanumerical characters
130151
131152 if user_input .isalpha ():
132153 url = f"https://example.com/foo#{ user_input } "
@@ -154,7 +175,8 @@ def partial_ssrf_7():
154175
155176 if re .fullmatch (r'.*[a-zA-Z0-9]+.*' , user_input ):
156177 url = f"https://example.com/foo#{ user_input } "
157- requests .get (url ) # NOT OK, but NOT FOUND - user input can contain arbitrary characters
178+ # NOT OK, but NOT FOUND - user input can contain arbitrary characters
179+ requests .get (url ) # $ MISSING: Alert[py/partial-ssrf]
158180
159181
160182 if re .match (r'^[a-zA-Z0-9]+$' , user_input ):
@@ -163,7 +185,8 @@ def partial_ssrf_7():
163185
164186 if re .match (r'[a-zA-Z0-9]+' , user_input ):
165187 url = f"https://example.com/foo#{ user_input } "
166- requests .get (url ) # NOT OK, but NOT FOUND - user input can contain arbitrary character as a suffix.
188+ # NOT OK, but NOT FOUND - user input can contain arbitrary character as a suffix.
189+ requests .get (url ) # $ MISSING: Alert[py/partial-ssrf]
167190
168191 reg = re .compile (r'^[a-zA-Z0-9]+$' )
169192
0 commit comments