12
12
13
13
from test import BaseTestCase
14
14
15
+
15
16
def do_post_req (mytestcase , ep , headers , payload ):
16
17
"""
17
18
Perform an actual POST request
@@ -22,15 +23,13 @@ def do_post_req(mytestcase, ep, headers, payload):
22
23
# print("--- Starting POST request to {}".format(ep))
23
24
sleep (0.05 )
24
25
r = self .client .open (
25
- ep ,
26
- method = 'POST' ,
27
- data = json .dumps (payload ),
28
- headers = headers )
26
+ ep , method = "POST" , data = json .dumps (payload ), headers = headers
27
+ )
29
28
# r = requests.post('{}'.format(ep), data=payload,
30
29
# headers=headers, timeout=20, allow_redirects=False)
31
30
except Exception as e :
32
31
print (" Exception connecting to {} with {}" .format (ep , str (e )))
33
- return ( {"status_code" : - 1 , "content" : "" })
32
+ return {"status_code" : - 1 , "content" : "" }
34
33
else :
35
34
# print(" POST request to {} returned status {}: {}".format(ep, r.status_code, r.data))
36
35
return r
@@ -45,22 +44,19 @@ def do_get_req(mytestcase, ep, headers):
45
44
try :
46
45
# print("--- Starting GET request to {}".format(ep))
47
46
sleep (0.05 )
48
- r = self .client .open (
49
- ep ,
50
- method = 'GET' ,
51
- headers = headers )
47
+ r = self .client .open (ep , method = "GET" , headers = headers )
52
48
# r = requests.get('{}'.format(ep), headers=headers,
53
49
# timeout=20, allow_redirects=False)
54
50
except Exception as e :
55
51
print (" Exception connecting to {} with {}" .format (ep , str (e )))
56
- return ( {"status_code" : - 1 , "content" : "" })
52
+ return {"status_code" : - 1 , "content" : "" }
57
53
else :
58
54
# print(" GET request to {} returned status {}: {}".format(ep,r.status_code, r.content))
59
- return ( r )
55
+ return r
60
56
61
57
62
58
def get_happyday_pattern (datatype ):
63
- fuzzdbfile = "test/fuzz-{}.txt" .format (re .sub (r' [^a-zA-Z]' , '' , datatype ))
59
+ fuzzdbfile = "test/fuzz-{}.txt" .format (re .sub (r" [^a-zA-Z]" , "" , datatype ))
64
60
fuzzdbfallbackfile = "test/fuzz-fallback.txt"
65
61
happydaystring = ""
66
62
if os .path .exists (fuzzdbfile ):
@@ -75,7 +71,7 @@ def get_happyday_pattern(datatype):
75
71
76
72
77
73
def get_fuzz_patterns (datatype ):
78
- fuzzdbfile = "test/fuzz-{}.txt" .format (re .sub (r' [^a-zA-Z]' , '' , datatype ))
74
+ fuzzdbfile = "test/fuzz-{}.txt" .format (re .sub (r" [^a-zA-Z]" , "" , datatype ))
79
75
fuzzdbfallbackfile = "test/fuzz-fallback.txt"
80
76
lines = []
81
77
if os .path .exists (fuzzdbfile ):
@@ -99,8 +95,9 @@ def generate_happy_day_url_from_pathvars(baseurl, path, pathvars):
99
95
for pathvar in pathvars :
100
96
datatype = pathvar .get ("schema" , {}).get ("type" , "fallback" )
101
97
happydaystring = get_happyday_pattern (datatype )
102
- url = url .replace ("{{{}}}" .format (
103
- pathvar .get ("name" )), happydaystring .rstrip ())
98
+ url = url .replace (
99
+ "{{{}}}" .format (pathvar .get ("name" )), happydaystring .rstrip ()
100
+ )
104
101
return url
105
102
106
103
@@ -113,19 +110,19 @@ def generate_urls_from_pathvars(baseurl, path, pathvars):
113
110
"""
114
111
urls = set ()
115
112
for pathvar in pathvars :
116
- if pathvar .get ('in' , None ) == ' path' and ' name' in pathvar .keys ():
113
+ if pathvar .get ("in" , None ) == " path" and " name" in pathvar .keys ():
117
114
datatype = pathvar .get ("schema" , {}).get ("type" , "fallback" )
118
115
lines = get_fuzz_patterns (datatype )
119
116
for line in lines :
120
117
url = "{}{}" .format (baseurl , path )
121
- url = url .replace ("{{{}}}" .format (
122
- pathvar .get ("name" )), line .rstrip ())
118
+ url = url .replace ("{{{}}}" .format (pathvar .get ("name" )), line .rstrip ())
123
119
for otherpathvar in pathvars :
124
- datatype = otherpathvar .get (
125
- "schema" , {}).get ("type" , "fallback" )
120
+ datatype = otherpathvar .get ("schema" , {}).get ("type" , "fallback" )
126
121
happydaystring = get_happyday_pattern (datatype )
127
- url = url .replace ("{{{}}}" .format (
128
- otherpathvar .get ("name" )), happydaystring .rstrip ())
122
+ url = url .replace (
123
+ "{{{}}}" .format (otherpathvar .get ("name" )),
124
+ happydaystring .rstrip (),
125
+ )
129
126
urls .add (url )
130
127
return urls
131
128
@@ -148,7 +145,11 @@ def generate_payloads_from_postvars(postvars):
148
145
datatype = postvars .get (param , {}).get ("type" , "" )
149
146
happydaystring = get_happyday_pattern (datatype )
150
147
if param == fuzzparam :
151
- if jsontype == "int" or datatype == "int" or datatype == "number" :
148
+ if (
149
+ jsontype == "int"
150
+ or datatype == "int"
151
+ or datatype == "number"
152
+ ):
152
153
try :
153
154
payload [param ] = int (line .rstrip ())
154
155
except ValueError :
@@ -172,13 +173,13 @@ def generate_payloads_from_postvars(postvars):
172
173
173
174
174
175
def do_post_fuzzing (* args , ** kwargs ):
175
- baseurl = kwargs .get (' baseurl' , "" )
176
- headers = kwargs .get (' headers' , {})
177
- path = kwargs .get (' path' , None )
178
- pathvars = kwargs .get (' pathvars' , {})
179
- postvars = kwargs .get (' postvars' , {})
180
- responses = kwargs .get (' responses' , [])
181
- self = kwargs .get (' mytestcase' , None )
176
+ baseurl = kwargs .get (" baseurl" , "" )
177
+ headers = kwargs .get (" headers" , {})
178
+ path = kwargs .get (" path" , None )
179
+ pathvars = kwargs .get (" pathvars" , {})
180
+ postvars = kwargs .get (" postvars" , {})
181
+ responses = kwargs .get (" responses" , [])
182
+ self = kwargs .get (" mytestcase" , None )
182
183
183
184
newresponses = []
184
185
for response in responses :
@@ -203,17 +204,17 @@ def do_get_fuzzing(*args, **kwargs):
203
204
"""
204
205
Perform fuzzing on a GET endpoint
205
206
"""
206
- baseurl = kwargs .get (' baseurl' , "" )
207
- headers = kwargs .get (' headers' , {})
208
- path = kwargs .get (' path' , None )
209
- pathvars = kwargs .get (' pathvars' , {})
210
- responses = kwargs .get (' responses' , [])
211
- self = kwargs .get (' mytestcase' , None )
207
+ baseurl = kwargs .get (" baseurl" , "" )
208
+ headers = kwargs .get (" headers" , {})
209
+ path = kwargs .get (" path" , None )
210
+ pathvars = kwargs .get (" pathvars" , {})
211
+ responses = kwargs .get (" responses" , [])
212
+ self = kwargs .get (" mytestcase" , None )
212
213
213
214
urls = generate_urls_from_pathvars (baseurl , path , pathvars )
214
215
stats = {}
215
- stats [' path' ] = path
216
- stats [' method' ] = ' GET'
216
+ stats [" path" ] = path
217
+ stats [" method" ] = " GET"
217
218
218
219
newresponses = []
219
220
for response in responses :
@@ -230,6 +231,7 @@ def do_get_fuzzing(*args, **kwargs):
230
231
self .assertIn (r .status_code , responses )
231
232
return True
232
233
234
+
233
235
def do_fuzzing (mytestcase , headers ):
234
236
235
237
self = mytestcase
@@ -238,52 +240,87 @@ def do_fuzzing(mytestcase, headers):
238
240
parser = ResolvingParser ("openapi/vAPI.yaml" )
239
241
spec = parser .specification # contains fully resolved specs as a dict
240
242
# print(json.dumps(parser.specification.get("paths").get("/employees/expenses/{expenses_id}/attachments").get("post"),indent=2))
241
- for path , pathvalues in spec .get ("paths" ,{}).items ():
242
- for method ,methodvalues in pathvalues .items ():
243
+ for path , pathvalues in spec .get ("paths" , {}).items ():
244
+ for method , methodvalues in pathvalues .items ():
243
245
pathvars = {}
244
246
# postvars = {}
245
- if method == ' get' :
246
- if ' parameters' in methodvalues .keys ():
247
- pathvars = methodvalues .get ("parameters" ,{})
248
- responses = list (methodvalues .get ("responses" ,{}).keys ())
247
+ if method == " get" :
248
+ if " parameters" in methodvalues .keys ():
249
+ pathvars = methodvalues .get ("parameters" , {})
250
+ responses = list (methodvalues .get ("responses" , {}).keys ())
249
251
# print("--------------------------------------------")
250
252
# print("GET fuzzing {}".format(path))
251
- do_get_fuzzing (mytestcase = self , baseurl = baseurl , headers = headers , path = path , pathvars = pathvars , responses = responses )
252
- if method == 'post' :
253
- responses = list (methodvalues .get ("responses" ,{}).keys ())
254
- if 'requestBody' in methodvalues .keys () and 'parameters' in methodvalues .keys ():
253
+ do_get_fuzzing (
254
+ mytestcase = self ,
255
+ baseurl = baseurl ,
256
+ headers = headers ,
257
+ path = path ,
258
+ pathvars = pathvars ,
259
+ responses = responses ,
260
+ )
261
+ if method == "post" :
262
+ responses = list (methodvalues .get ("responses" , {}).keys ())
263
+ if (
264
+ "requestBody" in methodvalues .keys ()
265
+ and "parameters" in methodvalues .keys ()
266
+ ):
255
267
pathvars = methodvalues .get ("parameters" )
256
- postvars = methodvalues .get ("requestBody" ,{}).get ("content" ,{}).get ("application/json" ,{}).get ("schema" ,{}).get ("properties" ,{})
268
+ postvars = (
269
+ methodvalues .get ("requestBody" , {})
270
+ .get ("content" , {})
271
+ .get ("application/json" , {})
272
+ .get ("schema" , {})
273
+ .get ("properties" , {})
274
+ )
257
275
# print("--------------------------------------------")
258
276
# print("POST fuzzing param URL {}:".format(path))
259
- do_post_fuzzing (mytestcase = self , baseurl = baseurl , headers = headers , path = path , pathvars = pathvars , postvars = postvars , responses = responses )
260
- elif 'requestBody' in methodvalues .keys ():
261
- postvars = methodvalues .get ("requestBody" ,{}).get ("content" ,{}).get ("application/json" ,{}).get ("schema" ,{}).get ("properties" ,{})
277
+ do_post_fuzzing (
278
+ mytestcase = self ,
279
+ baseurl = baseurl ,
280
+ headers = headers ,
281
+ path = path ,
282
+ pathvars = pathvars ,
283
+ postvars = postvars ,
284
+ responses = responses ,
285
+ )
286
+ elif "requestBody" in methodvalues .keys ():
287
+ postvars = (
288
+ methodvalues .get ("requestBody" , {})
289
+ .get ("content" , {})
290
+ .get ("application/json" , {})
291
+ .get ("schema" , {})
292
+ .get ("properties" , {})
293
+ )
262
294
# print("--------------------------------------------")
263
295
# print("POST fuzzing non-param URL {}:".format(path))
264
- do_post_fuzzing (mytestcase = self , baseurl = baseurl , headers = headers , path = path , postvars = postvars , responses = responses )
296
+ do_post_fuzzing (
297
+ mytestcase = self ,
298
+ baseurl = baseurl ,
299
+ headers = headers ,
300
+ path = path ,
301
+ postvars = postvars ,
302
+ responses = responses ,
303
+ )
265
304
266
305
267
306
class TestvAPI (BaseTestCase ):
268
-
269
307
def test_unauth_fuzzing (self ):
270
- headers = { "Content-type" : "application/json" }
308
+ headers = {"Content-type" : "application/json" }
271
309
do_fuzzing (self , headers )
272
310
273
311
def test_auth_fuzzing (self ):
274
- headers = { "Content-type" : "application/json" }
312
+ headers = {"Content-type" : "application/json" }
275
313
payload = {"username" : "user1" , "password" : "pass1" }
276
314
url = "/tokens"
277
315
r = self .client .open (
278
- url ,
279
- method = 'POST' ,
280
- data = json .dumps (payload ),
281
- headers = headers )
282
- self .assertEqual (r .status_code ,200 )
283
- self .assertRegex (r .json ['access' ]['token' ]['id' ], r'\w{32}' )
284
- token = r .json ['access' ]['token' ]['id' ]
316
+ url , method = "POST" , data = json .dumps (payload ), headers = headers
317
+ )
318
+ self .assertEqual (r .status_code , 200 )
319
+ self .assertRegex (r .json ["access" ]["token" ]["id" ], r"\w{32}" )
320
+ token = r .json ["access" ]["token" ]["id" ]
285
321
headers ["X-Auth-Token" ] = token
286
322
do_fuzzing (self , headers )
287
323
288
- if __name__ == '__main__' :
324
+
325
+ if __name__ == "__main__" :
289
326
unittest .main ()
0 commit comments