-
-
Notifications
You must be signed in to change notification settings - Fork 87
First push of new independent Python API for ZAP #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ __pycache__/ | |
*.py[cod] | ||
*$py.class | ||
|
||
.idea/ | ||
# C extensions | ||
*.so | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
include LICENSE requirements.txt requirements-extra.txt | ||
|
||
recursive-exclude * __pycache__ | ||
recursive-exclude * *.pyc | ||
recursive-exclude * *.pyo | ||
recursive-exclude * *.orig | ||
recursive-exclude * .DS_Store | ||
global-exclude __pycache__/* | ||
global-exclude .deps/* | ||
global-exclude *.so | ||
global-exclude *.pyd | ||
global-exclude *.pyc | ||
global-exclude .git* | ||
global-exclude .DS_Store | ||
global-exclude .mailmap |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# zap-api-python | ||
|
||
|
||
# Install | ||
|
||
.. code-block:: bash | ||
|
||
# pip install python-owasp-zap | ||
|
||
# Basic usage | ||
|
||
.. code-block:: python | ||
|
||
from zap import ZAPv24 | ||
|
||
zap = ZAPv24() | ||
|
||
print('Spidering target %s' % target) | ||
scanid = zap.spider.scan(target) | ||
|
||
# Give the Spider a chance to start | ||
time.sleep(2) | ||
|
||
while int(zap.spider.status(scanid)) < 100: | ||
print('Spider progress %: ' + zap.spider.status(scanid)) | ||
time.sleep(2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from __future__ import print_function | ||
|
||
import time | ||
|
||
from pprint import pprint | ||
from zap import ZAPv24 | ||
|
||
target = 'http://127.0.0.1' | ||
|
||
# By default ZAP API client will connect to port 8080 | ||
zap = ZAPv24() | ||
|
||
# Or, you can configure your own IP/Port | ||
# zap_9090 = ZAPv24(proxies={'http': '127.0.0.1:9090', 'https': '127.0.0.1:9090'}) | ||
|
||
# Use the line below if ZAP is not listening on port 8080, for example, if listening on port 8090 | ||
# zap = ZAPv24(proxies={'http': 'http://127.0.0.1:8090', 'https': 'http://127.0.0.1:8090'}) | ||
|
||
# do stuff | ||
print('Accessing target %s' % target) | ||
|
||
# try have a unique enough session... | ||
zap.urlopen(target) | ||
|
||
# Give the sites tree a chance to get updated | ||
time.sleep(2) | ||
|
||
print('Spidering target %s' % target) | ||
scanid = zap.spider.scan(target) | ||
|
||
# Give the Spider a chance to start | ||
time.sleep(2) | ||
|
||
while int(zap.spider.status(scanid)) < 100: | ||
print('Spider progress %: ' + zap.spider.status(scanid)) | ||
time.sleep(2) | ||
|
||
print('Spider completed') | ||
|
||
# Give the passive scanner a chance to finish | ||
time.sleep(5) | ||
|
||
print('Scanning target %s' % target) | ||
|
||
scanid = zap.ascan.scan(target) | ||
while int(zap.ascan.status(scanid)) < 100: | ||
print('Scan progress %: ' + zap.ascan.status(scanid)) | ||
time.sleep(5) | ||
|
||
print('Scan completed') | ||
|
||
# Report the results | ||
|
||
print('Hosts: ' + ', '.join(zap.core.hosts)) | ||
print('Alerts: ') | ||
pprint((zap.core.alerts())) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ujson |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
six | ||
requests | ||
requests-cache |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#!/usr/bin/env python | ||
|
||
""" | ||
Standard build script. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whats the process for building and releasing this library now? Be good to document it, esp for python noobs like me ;) Could be documented in this repo or on https://github.com/zaproxy/zaproxy/wiki/GeneratingTheFullRelease#generate-the-release-add-ons There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hahaha oks, no problem :) As a said above, to release a new version to Pypi, we'll need to do: Register the new package https://pypi.python.org/pypi?%3Aaction=login_form Then It'll necessary to register the new version, running (in python 2 o 3): Uploads
|
||
""" | ||
|
||
from __future__ import print_function | ||
|
||
from os.path import dirname, join | ||
|
||
try: | ||
from setuptools import setup, find_packages | ||
except ImportError: | ||
print("You must have setuptools installed to use setup.py. Exiting...") | ||
raise SystemExit(1) | ||
|
||
__docformat__ = 'restructuredtext' | ||
|
||
# Import requirements | ||
with open(join(dirname(__file__), 'requirements.txt')) as f: | ||
required = f.read().splitlines() | ||
|
||
# Import extra requirements | ||
with open(join(dirname(__file__), 'requirements-extra.txt')) as f: | ||
extra_required = f.read().splitlines() | ||
|
||
setup( | ||
name="python-owasp-zap", | ||
version="1.0.0", | ||
description="OWASP ZAP API client. Supported versions: 2.4", | ||
install_requires=required, | ||
extras_require={ | ||
'performance': extra_required, | ||
}, | ||
long_description="OWASP Zed Attack Proxy API python client", | ||
author="ZAP development team", | ||
author_email='', | ||
url="https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project", | ||
download_url="https://github.com/zaproxy/zap-api-python/archive/master.zip", | ||
platforms=['any'], | ||
license="ASL2.0", | ||
packages=find_packages(), | ||
classifiers=[ | ||
'License :: OSI Approved :: Apache Software License', | ||
'Topic :: Security', | ||
'Topic :: Software Development :: Libraries :: Python Modules', | ||
'Intended Audience :: Developers', | ||
'Intended Audience :: Information Technology', | ||
'Programming Language :: Python :: 2', | ||
'Programming Language :: Python :: 3', | ||
'Programming Language :: Python'], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Zed Attack Proxy (ZAP) and its related class files. | ||
# | ||
# ZAP is an HTTP/HTTPS proxy for assessing web application security. | ||
# | ||
# Copyright 2016 ZAP development team | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" | ||
Client implementation for using the ZAP pentesting proxy remotely. | ||
""" | ||
|
||
from .zap_24 import ZAPv24 | ||
|
||
# In next releases It will be available more version includes, like: | ||
# from .zap_25 import ZAPv25 | ||
|
||
|
||
__all__ = ["ZAPv24"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# Zed Attack Proxy (ZAP) and its related class files. | ||
# | ||
# ZAP is an HTTP/HTTPS proxy for assessing web application security. | ||
# | ||
# Copyright 2016 ZAP development team | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" | ||
Client implementation for using the ZAP pentesting proxy remotely. | ||
""" | ||
|
||
try: | ||
# High performance json library | ||
import ujson as json | ||
except ImportError: | ||
import json | ||
|
||
import six | ||
import requests | ||
import requests_cache | ||
requests_cache.install_cache('zap_cache', backend="memory") | ||
|
||
# Improving Python 2 & 3 compatibility | ||
if six.PY2: | ||
from urllib import urlencode, urlopen | ||
from urlparse import urlparse, urljoin | ||
else: | ||
from urllib.parse import urlparse, urlencode, urljoin | ||
from urllib.request import urlopen | ||
|
||
|
||
class _ZAP(object): | ||
""" | ||
Client API implementation for integrating with ZAP v2. | ||
""" | ||
|
||
def _expect_ok(self, json_data): | ||
""" | ||
Checks that we have an OK response, else raises an exception. | ||
|
||
:param json_data: the json data to look at. | ||
:type json_data: json | ||
""" | ||
if isinstance(json_data, list) and json_data[0] == u'OK': | ||
return json_data | ||
|
||
raise ZapError(*json_data.values()) | ||
|
||
def urlopen(self, *args, **kwargs): | ||
""" | ||
Opens a url forcing the proxies to be used. | ||
|
||
:param args: all non-keyword arguments. | ||
:type args: list() | ||
|
||
:param kwarg: all non-keyword arguments. | ||
:type kwarg: dict() | ||
""" | ||
# return urlopen(*args, **kwargs).read() | ||
return requests.get(*args, proxies=self.__proxies).text | ||
|
||
def status_code(self, *args, **kwargs): | ||
""" | ||
Open a url forcing the proxies to be used. | ||
|
||
:param args: all non-keyword arguments. | ||
:type args: list() | ||
|
||
:param kwarg: all non-keyword arguments. | ||
:type kwarg: dict() | ||
""" | ||
# return urlopen(*args, **kwargs).getcode() | ||
return requests.get(*args, proxies=self.__proxies).status_code | ||
|
||
def _request(self, url, get=None): | ||
""" | ||
Shortcut for a GET request. | ||
|
||
:param url: the url to GET at. | ||
:type url: str | ||
|
||
:param get: the dictionary to turn into GET variables. | ||
:type get: dict(str:str) | ||
""" | ||
if get is None: | ||
get = {} | ||
|
||
return json.loads(self.urlopen("%s?%s" % (url, urlencode(get)))) | ||
|
||
def _request_other(self, url, get=None): | ||
""" | ||
Shortcut for an API OTHER GET request. | ||
|
||
:param url: the url to GET at. | ||
:type url: str | ||
|
||
:param get: the dictionary to turn into GET variables. | ||
:type get: dict(str:str) | ||
""" | ||
if get is None: | ||
get = {} | ||
|
||
return self.urlopen("%s?%s" % (url, urlencode(get))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an aside, how much do people look at / use the examples? I've got a more complete example (more configurable, option to use ajax spider) that we could include later..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I love the examples. Although the documentation were really good, look a real example of program it's useful. So, I put in an independent directory.
Unlike Java, with Python, these examples are a complete programs. Without more dependencies, compilers, or so on. So there're os useful for programmers.
If you have more examples it could be great.