21
21
22
22
__docformat__ = 'restructuredtext'
23
23
24
- import json
25
- import urllib
24
+ import requests
25
+ from requests .packages .urllib3 .exceptions import InsecureRequestWarning
26
+
26
27
from acsrf import acsrf
27
28
from ascan import ascan
28
29
from ajaxSpider import ajaxSpider
@@ -58,8 +59,7 @@ class ZAPv2(object):
58
59
# base OTHER api url
59
60
base_other = 'http://zap/OTHER/'
60
61
61
- def __init__ (self , proxies = {'http' : 'http://127.0.0.1:8080' ,
62
- 'https' : 'http://127.0.0.1:8080' }):
62
+ def __init__ (self , proxies = None , apikey = None ):
63
63
"""
64
64
Creates an instance of the ZAP api client.
65
65
@@ -69,7 +69,11 @@ def __init__(self, proxies={'http': 'http://127.0.0.1:8080',
69
69
Note that all of the other classes in this directory are generated
70
70
new ones will need to be manually added to this file
71
71
"""
72
- self .__proxies = proxies
72
+ self .__proxies = proxies or {
73
+ 'http' : 'http://127.0.0.1:8080' ,
74
+ 'https' : 'http://127.0.0.1:8080'
75
+ }
76
+ self .__apikey = apikey
73
77
74
78
self .acsrf = acsrf (self )
75
79
self .ajaxSpider = ajaxSpider (self )
@@ -95,6 +99,15 @@ def __init__(self, proxies={'http': 'http://127.0.0.1:8080',
95
99
self .stats = stats (self )
96
100
self .users = users (self )
97
101
102
+ # not very nice, but prevents warnings when accessing the ZAP API via https
103
+ requests .packages .urllib3 .disable_warnings (InsecureRequestWarning )
104
+
105
+ # Currently create a new session for each request to prevent request failing
106
+ # e.g. when polling the spider status
107
+ #self.session = requests.Session()
108
+ #if apikey is not None:
109
+ # self.session.headers['X-ZAP-API-Key'] = apikey
110
+
98
111
def urlopen (self , * args , ** kwargs ):
99
112
"""
100
113
Opens a url forcing the proxies to be used.
@@ -103,25 +116,50 @@ def urlopen(self, *args, **kwargs):
103
116
- `args`: all non-keyword arguments.
104
117
- `kwargs`: all other keyword arguments.
105
118
"""
106
- kwargs ['proxies' ] = self .__proxies
107
- return urllib .urlopen (* args , ** kwargs ).read ()
119
+ # Must never leak the API key via proxied requests
120
+ return requests .get (* args , proxies = self .__proxies , verify = False , ** kwargs ).text
121
+
122
+ def _request_api (self , url , query = None ):
123
+ """
124
+ Shortcut for an API request. Will always add the apikey (if defined)
125
+
126
+ :Parameters:
127
+ - `url`: the url to GET at.
128
+ """
129
+ if not url .startswith ('http://zap/' ):
130
+ # Only allow requests to the API so that we never leak the apikey
131
+ raise ValueError ('A non ZAP API url was specified ' + url )
132
+ return ;
133
+
134
+ # In theory we should be able to reuse the session,
135
+ # but there have been problems with that
136
+ self .session = requests .Session ()
137
+ if self .__apikey is not None :
138
+ self .session .headers ['X-ZAP-API-Key' ] = self .__apikey
139
+
140
+ query = query or {}
141
+ if self .__apikey is not None :
142
+ # Add the apikey to get params for backwards compatibility
143
+ if not query .get ('apikey' ):
144
+ query ['apikey' ] = self .__apikey
145
+ return self .session .get (url , params = query , proxies = self .__proxies , verify = False )
108
146
109
147
def _request (self , url , get = None ):
110
148
"""
111
149
Shortcut for a GET request.
112
150
113
151
:Parameters:
114
152
- `url`: the url to GET at.
115
- - `get`: the disctionary to turn into GET variables.
153
+ - `get`: the dictionary to turn into GET variables.
116
154
"""
117
- return json . loads ( self .urlopen (url + '?' + urllib . urlencode ( get or {})) )
155
+ return self ._request_api (url , get ). json ( )
118
156
119
- def _request_other (self , url , get = {} ):
157
+ def _request_other (self , url , get = None ):
120
158
"""
121
159
Shortcut for an API OTHER GET request.
122
160
123
161
:Parameters:
124
162
- `url`: the url to GET at.
125
- - `get`: the disctionary to turn into GET variables.
163
+ - `get`: the dictionary to turn into GET variables.
126
164
"""
127
- return self .urlopen (url + '?' + urllib . urlencode ( get or {}))
165
+ return self ._request_api (url , get ). text
0 commit comments