add initial sphinx rst framework
this change adds a structure for creating improved sphinx/restructured text documentation. the initial commit only brings over the information from the readme with some minor adjustments for titles and separating content into sections. Change-Id: If1a4cf7d046e784d84571a7a52480daab7d2be5c
This commit is contained in:
parent
3a2df44a38
commit
afd4cca2fd
77
doc/source/conf.py
Normal file
77
doc/source/conf.py
Normal file
@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
# 'sphinx.ext.intersphinx',
|
||||
'oslosphinx'
|
||||
]
|
||||
|
||||
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
||||
# text edit cycles.
|
||||
# execute "export SPHINX_DEBUG=1" in your terminal to disable
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Syntribos'
|
||||
copyright = u'2015, OpenStack Foundation'
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
add_module_names = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
# html_theme_path = ["."]
|
||||
# html_theme = '_theme'
|
||||
# html_static_path = ['static']
|
||||
html_theme_options = {}
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
]
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
# intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
|
92
doc/source/configuration.rst
Normal file
92
doc/source/configuration.rst
Normal file
@ -0,0 +1,92 @@
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Copy the data files from Syntribos data directory to .opencafe/data directory created during "cafe-config init". This directory contains the fuzz string files. Copy the example configuration file to .opencafe/configs directory created during "cafe-config init".
|
||||
|
||||
::
|
||||
|
||||
$ cp data/* .opencafe/data/
|
||||
$ cp examples/configs/keystone.config .opencafe/configs/.
|
||||
|
||||
Modify the configuration files to update your keystone URL, API endpoint
|
||||
and user credentials.
|
||||
|
||||
::
|
||||
|
||||
$ vi .opencafe/configs/keystone.config
|
||||
|
||||
Example configuration file:
|
||||
|
||||
::
|
||||
|
||||
[syntribos]
|
||||
endpoint=<yourapiendpoint>
|
||||
|
||||
[user]
|
||||
username=<yourusername>
|
||||
password=<yourpassword>
|
||||
user_id=<youruserid>
|
||||
|
||||
|
||||
[auth]
|
||||
endpoint=<yourkeystoneurl>
|
||||
|
||||
Your can create a directory to store the payloads for the resources
|
||||
being tested. The payloads under examples directory can give you quick
|
||||
start.
|
||||
|
||||
::
|
||||
|
||||
$ mkdir payloads
|
||||
$ mkdir payloads/keystone
|
||||
$ cp examples/payloads/keystone/* payloads/keystone/.
|
||||
|
||||
Here are some examples for payload files
|
||||
|
||||
::
|
||||
|
||||
$ vi payloads/keystone/domains_post.txt
|
||||
|
||||
::
|
||||
|
||||
POST /v3/domains HTTP/1.1
|
||||
Accept: application/json
|
||||
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|
|
||||
Content-type: application/json
|
||||
|
||||
{
|
||||
"domain": {
|
||||
"description": "Domain description",
|
||||
"enabled": true,
|
||||
"name": "CALL_EXTERNAL|syntribos.extensions.random_data.client:get_uuid:[]|"
|
||||
}
|
||||
}
|
||||
|
||||
::
|
||||
|
||||
$ vi payloads/keystone/domains_patch.txt
|
||||
|
||||
::
|
||||
|
||||
PATCH /v3/domains/c45412aa3cb74824a222c2f051bd62ac HTTP/1.1
|
||||
Accept: application/json
|
||||
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|
|
||||
Content-type: application/json
|
||||
|
||||
{
|
||||
"domain": {
|
||||
"description": "Domain description",
|
||||
"enabled": true,
|
||||
"name": "test name"
|
||||
}
|
||||
}
|
||||
|
||||
::
|
||||
|
||||
$ vi payloads/keystone/domains_get.txt
|
||||
|
||||
::
|
||||
|
||||
GET /v3/domains/{c45412aa3cb74824a222c2f051bd62ac} HTTP/1.1
|
||||
Accept: application/json
|
||||
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|
|
44
doc/source/index.rst
Normal file
44
doc/source/index.rst
Normal file
@ -0,0 +1,44 @@
|
||||
Syntribos
|
||||
=========
|
||||
|
||||
Syntribos is an Automated API Security Testing Tool utilizing the `Open
|
||||
CAFE Framework <https://github.com/stackforge/opencafe>`__.
|
||||
|
||||
Given a simple configuration file and an example HTTP request, Syntribos
|
||||
can replace any API URL, URL parameter, HTTP header and request body
|
||||
field with a given set of strings. This is similar to Burp Proxy's
|
||||
Intruder sniper attack, but Syntribos iterates through each position
|
||||
automatically. Syntribos aims to automatically detect common security
|
||||
defects such as SQL injection, LDAP injection, buffer overflow, etc. In
|
||||
addition, Syntribos can be used to help identifying new security defects
|
||||
by fuzzing.
|
||||
|
||||
Syntribos has the capability to test any API, but is designed with
|
||||
`OpenStack <http://http://www.openstack.org/>`__ applications in mind.
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
installation
|
||||
configuration
|
||||
running
|
||||
logging
|
||||
test.anatomy
|
||||
unittests
|
||||
|
||||
|
||||
Project information
|
||||
-------------------
|
||||
|
||||
* Free software: `Apache license`_
|
||||
* `Launchpad project`_
|
||||
* `Blueprints`_
|
||||
* `Bugs`_
|
||||
|
||||
.. _Apache license: https://github.com/openstack/syntribos/blob/master/LICENSE
|
||||
.. _Launchpad project: https://launchpad.net/syntribos
|
||||
.. _Blueprints: https://blueprints.launchpad.net/syntribos
|
||||
.. _Bugs: https://bugs.launchpad.net/syntribos
|
31
doc/source/installation.rst
Normal file
31
doc/source/installation.rst
Normal file
@ -0,0 +1,31 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
Syntribos can be `installed with
|
||||
pip <https://pypi.python.org/pypi/pip>`__ from the git repository.
|
||||
|
||||
- Clone the repository and install it using pip
|
||||
|
||||
::
|
||||
|
||||
$ git clone https://github.com/openstack/syntribos.git
|
||||
$ cd syntribos
|
||||
$ pip install . --upgrade
|
||||
|
||||
- To enable autocomplete for Syntribos, run the command.
|
||||
|
||||
::
|
||||
|
||||
$ . scripts/syntribos-completion
|
||||
|
||||
- Create a directory named .opencafe in the user's home directory, or in the case of a python virtualenv, in the virtualenv root folder.
|
||||
|
||||
::
|
||||
|
||||
$ cafe-config init
|
||||
|
||||
- Install the http library that gives you the minimum plugins required to use Syntribos.
|
||||
|
||||
::
|
||||
|
||||
$ cafe-config plugins install http
|
92
doc/source/logging.rst
Normal file
92
doc/source/logging.rst
Normal file
@ -0,0 +1,92 @@
|
||||
Syntribos logging
|
||||
=================
|
||||
|
||||
Syntribos takes advantage of the OpenCafe logging facility. Logs are
|
||||
found in ``.opencafe/logs/`` Logs are then arranged in directories based
|
||||
on each Syntribos configuration file, and then by date and time. Each
|
||||
log filename has an easy to follow naming convention.
|
||||
|
||||
::
|
||||
|
||||
$ ls .opencafe/logs/keystone.config/2015-08-18_14_44_04.333088/
|
||||
cafe.master.log
|
||||
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str1_model1.log
|
||||
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str1_model2.log
|
||||
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str1_model3.log
|
||||
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str2_model1.log
|
||||
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str2_model2.log
|
||||
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str2_model3.log
|
||||
|
||||
Each log file includes the request details:
|
||||
|
||||
::
|
||||
|
||||
------------
|
||||
REQUEST SENT
|
||||
------------
|
||||
request method..: POST
|
||||
request url.....: https://yourapiendpoint/v3/domains
|
||||
request params..:
|
||||
request headers.: {'Content-Length': '46', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Accept': 'application/json', 'User-Agent': 'python-requests/2.7.0 CPython/2.7.9 Darwin/11.4.2', 'Host': 'yourapiendpoint', 'X-Auth-Token': u'9b1ed3d1cc69491ab914dcb6ced00440', 'Content-type': 'application/json'}
|
||||
request body....: {"domain": {"description": "Domain description","enabled": "-1","name": u'ce9871c4-a0a1-4fbe-88db-f0729b43172c'}}
|
||||
|
||||
2015-08-18 14:44:12,464: DEBUG: cafe.engine.http.client:
|
||||
|
||||
and the response:
|
||||
|
||||
::
|
||||
|
||||
-----------------
|
||||
RESPONSE RECEIVED
|
||||
-----------------
|
||||
response status..: <Response [406]>
|
||||
response time....: 1.32309699059
|
||||
response headers.: {'content-length': '112', 'server': 'nginx', 'connection': 'keep-alive', 'date': 'Tue, 18 Aug 2015 19:44:11 GMT', 'content-type': 'application/json; charset=UTF-8'}
|
||||
response body....: {"message": "The server could not comply with the request since it is either malformed or otherwise incorrect."}
|
||||
-------------------------------------------------------------------------------
|
||||
2015-08-18 14:44:12,465: INFO: root: ========================================================
|
||||
2015-08-18 14:44:12,465: INFO: root: Test Case....: test_case
|
||||
2015-08-18 14:44:12,465: INFO: root: Created At...: 2015-08-18 14:44:11.139070
|
||||
2015-08-18 14:44:12,465: INFO: root: No Test description.
|
||||
2015-08-18 14:44:12,465: INFO: root: ========================================================
|
||||
2015-08-18 14:44:12,465: WARNING: cafe.engine.models.data_interfaces.ConfigParserDataSource: No section: 'fuzz'. Using default value '200.0' instead
|
||||
2015-08-18 14:44:12,465: DEBUG: root: Validate Length:
|
||||
Initial request length: 52
|
||||
Initial response length: 112
|
||||
Request length: 46
|
||||
Response length: 112
|
||||
Request difference: -6
|
||||
Response difference: 0
|
||||
Precent difference: 0.0
|
||||
Config percent: 200.0
|
||||
|
||||
Note the "Validate Length" section at the end. This is used to help
|
||||
determine whether the test passed or failed. If the *Percent difference*
|
||||
exceeds the *Config percent* the test has failed. The *Config percent*
|
||||
is set in ``syntribos/syntribos/tests/fuzz/config.py``. The *Percent
|
||||
difference* is calculated in
|
||||
``syntribos/syntribos/tests/fuzz/base_fuzz.py``. Additional validations,
|
||||
such as looking for SQL strings or stack traces, can be added to
|
||||
individual tests.
|
||||
|
||||
The Logs also contain a summary of data related to the test results
|
||||
above:
|
||||
|
||||
::
|
||||
|
||||
2015-08-18 14:44:12,466: INFO: root: ========================================================
|
||||
2015-08-18 14:44:12,466: INFO: root: Test Case......: test_case
|
||||
2015-08-18 14:44:12,466: INFO: root: Result.........: Passed
|
||||
2015-08-18 14:44:12,466: INFO: root: Start Time.....: 2015-08-18 14:44:12.464843
|
||||
2015-08-18 14:44:12,466: INFO: root: Elapsed Time...: 0:00:00.001203
|
||||
2015-08-18 14:44:12,466: INFO: root: ========================================================
|
||||
2015-08-18 14:44:12,467: INFO: root: ========================================================
|
||||
2015-08-18 14:44:12,467: INFO: root: Fixture........: syntribos.tests.fuzz.all_attacks.(agent_patch.txt)_(ALL_ATTACKS_BODY)_(all-attacks.txt)_str1_model1
|
||||
2015-08-18 14:44:12,467: INFO: root: Result.........: Passed
|
||||
2015-08-18 14:44:12,467: INFO: root: Start Time.....: 2015-08-18 14:44:11.139070
|
||||
2015-08-18 14:44:12,467: INFO: root: Elapsed Time...: 0:00:01.328030
|
||||
2015-08-18 14:44:12,468: INFO: root: Total Tests....: 1
|
||||
2015-08-18 14:44:12,468: INFO: root: Total Passed...: 1
|
||||
2015-08-18 14:44:12,468: INFO: root: Total Failed...: 0
|
||||
2015-08-18 14:44:12,468: INFO: root: Total Errored..: 0
|
||||
2015-08-18 14:44:12,468: INFO: root: ========================================================
|
16
doc/source/running.rst
Normal file
16
doc/source/running.rst
Normal file
@ -0,0 +1,16 @@
|
||||
Running syntribos
|
||||
=================
|
||||
|
||||
To execute a Syntribos test, run ``syntribos`` specifying the configuration
|
||||
file and payload file(s) you want to use.
|
||||
|
||||
::
|
||||
|
||||
$ syntribos keystone.config payloads/keystone/domains_post.txt
|
||||
|
||||
To run ``syntribos`` against all payload files, just specify the payload
|
||||
directory:
|
||||
|
||||
::
|
||||
|
||||
$ syntribos keystone.config payloads/keystone/
|
74
doc/source/test.anatomy.rst
Normal file
74
doc/source/test.anatomy.rst
Normal file
@ -0,0 +1,74 @@
|
||||
Basic syntribos test anatomy
|
||||
============================
|
||||
|
||||
**Test Types**
|
||||
|
||||
The tests included at release time include LDAP injection, SQL
|
||||
injection, integer overflow and the generic all\_attacks.
|
||||
|
||||
In order to run a specific test, simply use the ``-t, --test-types``
|
||||
option and provide `syntribos` with a keyword or keywords to match from
|
||||
the test files located in ``syntribos/tests/fuzz/``.
|
||||
|
||||
For SQL injection tests, use:
|
||||
|
||||
::
|
||||
|
||||
$ syntribos keystone.config payloads/keystone/domains_post.txt -t SQL
|
||||
|
||||
For SQL injection tests against the payload body only, use:
|
||||
|
||||
::
|
||||
|
||||
$ syntribos keystone.config payloads/keystone/domains_post.txt -t SQL_INJECTION_BODY
|
||||
|
||||
For all tests against HTTP headers only, use:
|
||||
|
||||
::
|
||||
|
||||
$ syntribos keystone.config payloads/keystone/domains_post.txt -t HEADERS
|
||||
|
||||
**Call External**
|
||||
|
||||
Syntribos payload files can be supplemented with variable data, or data
|
||||
retrieved from external sources. This is handled using 'extensions.'
|
||||
|
||||
Extensions are found in ``syntribos/syntribos/extensions/`` .
|
||||
|
||||
One example packaged with Syntribos enables the tester to obtain an auth
|
||||
token from keystone/identity. The code is located in
|
||||
``identity/client.py``
|
||||
|
||||
To make use of this extension, add the following to the header of your
|
||||
payload file:
|
||||
|
||||
::
|
||||
|
||||
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|
|
||||
|
||||
The "user" string indicates the data from the configuration file we
|
||||
added in ``opencafe/configs/keystone.config``
|
||||
|
||||
Another example is found in ``random_data/client.py`` . This returns a
|
||||
UUID when random but unique data is needed. This can be used in place of
|
||||
usernames when fuzzing a create user call.
|
||||
|
||||
::
|
||||
|
||||
"username": "CALL_EXTERNAL|syntribos.extensions.random_data.client:get_uuid:[]|",
|
||||
|
||||
The extension function can return one value or be used as a generator if
|
||||
you want it to change for each test.
|
||||
|
||||
**Action Field**
|
||||
|
||||
While Syntribos is designed to test all fields in a request, it can also
|
||||
ignore specific fields through the use of Action Fields. If you want to
|
||||
fuzz against a static object ID, use the Action Field indicator as
|
||||
follows:
|
||||
|
||||
::
|
||||
|
||||
"ACTION_FIELD:id": "1a16f348-c8d5-42ec-a474-b1cdf78cf40f",
|
||||
|
||||
The ID provided will remain static for every test.
|
8
doc/source/unittests.rst
Normal file
8
doc/source/unittests.rst
Normal file
@ -0,0 +1,8 @@
|
||||
Executing unittests
|
||||
===================
|
||||
|
||||
Navigate to the ``syntribos`` root directory
|
||||
|
||||
::
|
||||
|
||||
$ python -m unittest discover syntribos/ -p ut_*.py
|
@ -19,3 +19,8 @@ classifier =
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
syntribos = syntribos.runner:entry_point
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
build-dir = doc/build
|
||||
source-dir = doc/source
|
||||
|
12
tox.ini
12
tox.ini
@ -4,16 +4,24 @@ skipsdist = True
|
||||
|
||||
[testenv]
|
||||
usedevelop = True
|
||||
install_command = pip install -U {opts} {packages}
|
||||
install_command = pip install -U {opts} {packages}
|
||||
setenv=VIRTUAL_ENV={envdir}
|
||||
deps=-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
commands = cafe-config plugins install http
|
||||
commands = cafe-config plugins install http
|
||||
python setup.py testr --coverage --slowest --testr-args='{posargs}'
|
||||
coverage combine
|
||||
coverage report -m
|
||||
coverage erase
|
||||
|
||||
[testenv:docs]
|
||||
commands =
|
||||
rm -rf doc/html doc/build
|
||||
rm -rf doc/source/apidoc doc/source/api
|
||||
python setup.py build_sphinx
|
||||
whitelist_externals =
|
||||
rm
|
||||
|
||||
[testenv:pep8]
|
||||
commands=flake8 {posargs} syntribos
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user