Simplified imports and added constants

Issues, Constants, and Results are now imported in the __init__.py of
the module

Change-Id: I805c9df4f8b838d63e2a7d04f5998718a7bf4ecb
This commit is contained in:
michael.dong@rackspace.com 2016-06-20 15:06:02 -05:00
parent 08a84a78dd
commit 445e12362e
13 changed files with 191 additions and 155 deletions

View File

@ -0,0 +1,16 @@
# Copyright 2016 Rackspace
#
# 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.
from syntribos.issue import Issue # flake8: noqa
from syntribos.constants import *
from syntribos.result import IssueTestResult # flake8: noqa

19
syntribos/constants.py Normal file
View File

@ -0,0 +1,19 @@
# Copyright 2016 Rackspace
#
# 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.
LOW = 1
MEDIUM = 2
HIGH = 3
RANKING = ['Undefined', 'Low', 'Medium', 'High']

View File

@ -13,6 +13,8 @@
# limitations under the License.
import json
import syntribos
class JSONFormatter(object):
@ -48,11 +50,12 @@ class JSONFormatter(object):
defect_type = issue.defect_type
if defect_type not in issues_by_url:
sev_rating = syntribos.RANKING[issue.severity]
issues_by_url[defect_type] = {
'description': issue.text,
'severity': issue.severity
'severity': sev_rating
}
machine_output['stats'][issue.severity] += 1
machine_output['stats'][sev_rating] += 1
issues_by_defect = issues_by_url[defect_type]
if issue.impacted_parameter:
@ -62,6 +65,7 @@ class JSONFormatter(object):
name = issue.impacted_parameter.name
content_type = issue.content_type
payload_string = issue.impacted_parameter.trunc_fuzz_string
conf_rating = syntribos.RANKING[issue.confidence]
param = {
'method': method,
'location': loc,
@ -73,7 +77,7 @@ class JSONFormatter(object):
payload_obj = {
'strings': [payload_string],
'param': param,
'confidence': issue.confidence
'confidence': conf_rating
}
if 'payloads' not in issues_by_defect:
issues_by_defect['payloads'] = [payload_obj]
@ -97,7 +101,7 @@ class JSONFormatter(object):
issues_by_defect['payloads'].append(payload_obj)
else:
issues_by_defect['confidence'] = issue.confidence
issues_by_defect['confidence'] = conf_rating
output = json.dumps(machine_output, sort_keys=True,
indent=2, separators=(',', ': '))

View File

@ -13,8 +13,8 @@
# limitations under the License.
import os
import syntribos
from syntribos.clients.http import client
from syntribos.issue import Issue
import syntribos.tests.auth.datagen
from syntribos.tests import base
@ -67,10 +67,11 @@ class BaseAuthTestCase(base.BaseTestCase):
" therefore it indicates that authentication with"
" another user's token was successful.")
self.register_issue(
Issue(test="try_alt_user_token",
severity="High",
text=text,
assertions=[(self.assertTrue, self.resp.status_code == 404)])
syntribos.Issue(
test="try_alt_user_token",
severity=syntribos.HIGH,
text=text,
assertions=[(self.assertTrue, self.resp.status_code == 404)])
)
self.test_issues()

View File

@ -15,8 +15,8 @@ import os
from six.moves.urllib.parse import urlparse
import syntribos
from syntribos.clients.http import client
from syntribos.issue import Issue
from syntribos.tests import base
import syntribos.tests.fuzz.config
import syntribos.tests.fuzz.datagen
@ -137,29 +137,28 @@ class BaseFuzzTestCase(base.BaseTestCase):
if self.resp.status_code >= 500:
self.register_issue(
Issue(test="500_errors",
severity="Low",
confidence="High",
text=("This request returns an error with status code "
"{0}, which might indicate some server-side fault "
"that could lead to further vulnerabilities"
).format(self.resp.status_code)
)
syntribos.Issue(
test="500_errors",
severity=syntribos.LOW,
confidence=syntribos.HIGH,
text=("This request returns an error with status code "
"{0}, which might indicate some server-side fault "
"that could lead to further vulnerabilities"
).format(self.resp.status_code))
)
if (not self.validate_length() and
self.resp.status_code == self.init_response.status_code):
self.register_issue(
Issue(test="length_diff",
severity="Low",
confidence="Low",
text=("The difference in length between the response to "
"the baseline request and the request returned "
"when sending an attack string exceeds {0} "
"percent, which could indicate a vulnerability "
"to injection attacks")
.format(self.config.percent)
)
syntribos.Issue(
test="length_diff",
severity=syntribos.LOW,
confidence=syntribos.LOW,
text=("The difference in length between the response to "
"the baseline request and the request returned "
"when sending an attack string exceeds {0} "
"percent, which could indicate a vulnerability "
"to injection attacks").format(self.config.percent))
)
def test_case(self):

View File

@ -11,7 +11,7 @@
# 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.
from syntribos.issue import Issue
import syntribos
from syntribos.tests.fuzz import base_fuzz
@ -40,28 +40,28 @@ class BufferOverflowBody(base_fuzz.BaseFuzzTestCase):
failed_strings = self.data_driven_failure_cases()
if failed_strings:
self.register_issue(
Issue(test="bof_strings",
severity="Medium",
confidence="Low",
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful buffer overflow "
"attack, have been found in the response. This "
"could indicate a vulnerability to buffer "
"overflow attacks.").format(failed_strings)
)
syntribos.Issue(
test="bof_strings",
severity=syntribos.MEDIUM,
confidence=syntribos.LOW,
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful buffer overflow "
"attack, have been found in the response. This "
"could indicate a vulnerability to buffer "
"overflow attacks.").format(failed_strings))
)
time_diff = self.config.time_difference_percent / 100
if (self.resp.elapsed.total_seconds() >
time_diff * self.init_response.elapsed.total_seconds()):
self.register_issue(
Issue(test="bof_timing",
severity="Medium",
confidence="Medium",
text=("The time it took to resolve a request with a "
"long string was too long compared to the "
"baseline request. This could indicate a "
"vulnerability to buffer overflow attacks")
)
syntribos.Issue(
test="bof_timing",
severity=syntribos.MEDIUM,
confidence=syntribos.MEDIUM,
text=("The time it took to resolve a request with a "
"long string was too long compared to the "
"baseline request. This could indicate a "
"vulnerability to buffer overflow attacks"))
)

View File

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from syntribos.issue import Issue
import syntribos
from syntribos.tests.fuzz import base_fuzz
@ -31,29 +31,29 @@ class CommandInjectionBody(base_fuzz.BaseFuzzTestCase):
failed_strings = self.data_driven_failure_cases()
if failed_strings:
self.register_issue(
Issue(test="command_injection",
severity="High",
confidence="Medium",
text=("A string known to be commonly returned after a "
"successful command injection attack was "
"included in the response. This could indicate "
"a vulnerability to command injection "
"attacks.").format(failed_strings)
)
syntribos.Issue(
test="command_injection",
severity=syntribos.HIGH,
confidence=syntribos.MEDIUM,
text=("A string known to be commonly returned after a "
"successful command injection attack was "
"included in the response. This could indicate "
"a vulnerability to command injection "
"attacks.").format(failed_strings))
)
time_diff = self.config.time_difference_percent / 100
if (self.resp.elapsed.total_seconds() >
time_diff * self.init_response.elapsed.total_seconds()):
self.register_issue(
Issue(test="command_injection",
severity="High",
confidence="Medium",
text=("The time elapsed between the sending of "
"the request and the arrival of the res"
"ponse exceeds the expected amount of time, "
"suggesting a vulnerability to command "
"injection attacks.").format(self.resp.elapsed)
)
syntribos.Issue(
test="command_injection",
severity=syntribos.HIGH,
confidence=syntribos.MEDIUM,
text=("The time elapsed between the sending of "
"the request and the arrival of the res"
"ponse exceeds the expected amount of time, "
"suggesting a vulnerability to command "
"injection attacks.").format(self.resp.elapsed))
)

View File

@ -11,7 +11,7 @@
# 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.
from syntribos.issue import Issue
import syntribos
from syntribos.tests.fuzz import base_fuzz
@ -25,14 +25,14 @@ class IntOverflowBody(base_fuzz.BaseFuzzTestCase):
if (self.resp.elapsed.total_seconds() >
time_diff * self.init_response.elapsed.total_seconds()):
self.register_issue(
Issue(test="int_timing",
severity="Medium",
confidence="Medium",
text=("The time it took to resolve a request with an "
"invalid integer was too long compared to the "
"baseline request. This could indicate a "
"vulnerability to buffer overflow attacks")
)
syntribos.Issue(
test="int_timing",
severity=syntribos.MEDIUM,
confidence=syntribos.MEDIUM,
text=("The time it took to resolve a request with an "
"invalid integer was too long compared to the "
"baseline request. This could indicate a "
"vulnerability to buffer overflow attacks"))
)

View File

@ -11,7 +11,7 @@
# 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.
from syntribos.issue import Issue
import syntribos
from syntribos.tests.fuzz import base_fuzz
@ -44,27 +44,27 @@ class SQLInjectionBody(base_fuzz.BaseFuzzTestCase):
failed_strings = self.data_driven_failure_cases()
if failed_strings:
self.register_issue(
Issue(test="sql_strings",
severity="Medium",
confidence="Low",
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful SQL injection attack"
", have been found in the response. This could "
"indicate a vulnerability to SQL injection "
"attacks."
).format(failed_strings)
)
syntribos.Issue(
test="sql_strings",
severity=syntribos.MEDIUM,
confidence=syntribos.LOW,
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful SQL injection attack"
", have been found in the response. This could "
"indicate a vulnerability to SQL injection "
"attacks."
).format(failed_strings))
)
time_diff = self.config.time_difference_percent / 100
if (self.resp.elapsed.total_seconds() >
time_diff * self.init_response.elapsed.total_seconds()):
self.register_issue(
Issue(test="sql_timing",
severity="Medium",
confidence="Medium",
text=(
"A response to one of our payload requests has "
syntribos.Issue(
test="sql_timing",
severity=syntribos.MEDIUM,
confidence=syntribos.MEDIUM,
text=("A response to one of our payload requests has "
"taken too long compared to the baseline request. "
"This could indicate a vulnerability to time-based "
"SQL injection attacks"))

View File

@ -13,7 +13,7 @@
# limitations under the License.
import os
from syntribos.issue import Issue
import syntribos
from syntribos.tests.fuzz import base_fuzz
import syntribos.tests.fuzz.datagen
@ -84,15 +84,15 @@ class XMLExternalEntityBody(base_fuzz.BaseFuzzTestCase):
failed_strings = self.data_driven_failure_cases()
if failed_strings:
self.register_issue(
Issue(test="xml_strings",
severity="Medium",
confidence="Low",
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful XML external entity "
"attack, have been found in the response. This "
"could indicate a vulnerability to XML external "
"entity attacks.").format(failed_strings)
)
syntribos.Issue(
test="xml_strings",
severity=syntribos.MEDIUM,
confidence=syntribos.LOW,
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful XML external entity "
"attack, have been found in the response. This "
"could indicate a vulnerability to XML external "
"entity attacks.").format(failed_strings))
)
time_diff = self.config.time_difference_percent / 100
@ -100,11 +100,12 @@ class XMLExternalEntityBody(base_fuzz.BaseFuzzTestCase):
if (self.resp.elapsed.total_seconds() >
time_diff * self.init_response.elapsed.total_seconds()):
self.register_issue(
Issue(test="xml_timing",
severity="Medium",
confidence="Medium",
text=("The time it took to resolve a request with an "
"invalid URL in the DTD takes too long compared "
"to the baseline request. This could reflect a "
"vulnerability to an XML external entity attack."))
syntribos.Issue(
test="xml_timing",
severity=syntribos.MEDIUM,
confidence=syntribos.MEDIUM,
text=("The time it took to resolve a request with an "
"invalid URL in the DTD takes too long compared "
"to the baseline request. This could reflect a "
"vulnerability to an XML external entity attack."))
)

View File

@ -11,7 +11,7 @@
# 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.
from syntribos.issue import Issue
import syntribos
from syntribos.tests.fuzz import base_fuzz
@ -27,20 +27,20 @@ class XSSBody(base_fuzz.BaseFuzzTestCase):
if 'content-type' in self.init_request.headers:
content_type = self.init_request.headers['content-type']
if 'html' in content_type:
sev = "Medium"
sev = syntribos.MEDIUM
else:
sev = "Low"
sev = syntribos.LOW
else:
sev = "Low"
sev = syntribos.LOW
if failed_strings:
self.register_issue(
Issue(test="xss_strings",
severity=sev,
confidence="Low",
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful XSS "
"attack, have been found in the response. This "
"could indicate a vulnerability to XSS "
"attacks.").format(failed_strings)
)
syntribos.Issue(
test="xss_strings",
severity=sev,
confidence=syntribos.LOW,
text=("The string(s): \'{0}\', known to be commonly "
"returned after a successful XSS "
"attack, have been found in the response. This "
"could indicate a vulnerability to XSS "
"attacks.").format(failed_strings))
)

View File

@ -13,9 +13,9 @@
# limitations under the License.
import os
import syntribos
from syntribos.clients.http import client
from syntribos.clients.http import parser
from syntribos.issue import Issue
from syntribos.tests import base
@ -43,40 +43,37 @@ class CorsHeader(base.BaseTestCase):
if 'Access-Control-Allow-Origin' in self.resp.headers:
if self.resp.headers['Access-Control-Allow-Origin'] == "*":
self.register_issue(
Issue(test="CORS_HEADER",
severity="Medium",
confidence="High",
text=("CORS header `Access-Control-Allow-Origin` set"
" to a wild character, this header should"
" always be set to a white listed set of URIs"
)
)
syntribos.Issue(
test="CORS_HEADER",
severity=syntribos.MEDIUM,
confidence=syntribos.HIGH,
text=("CORS header `Access-Control-Allow-Origin` set"
" to a wild character, this header should"
" always be set to a white listed set of URIs"))
)
if 'Access-Control-Allow-Methods' in self.resp.headers:
if self.resp.headers['Access-Control-Allow-Methods'] == "*":
self.register_issue(
Issue(test="CORS_HEADER",
severity="Low",
confidence="High",
text=("CORS header `Access-Control-Allow-Methods`"
" set to a wild character,it is a good"
" practice to give a white list of allowed"
" methods."
)
)
syntribos.Issue(
test="CORS_HEADER",
severity=syntribos.LOW,
confidence=syntribos.HIGH,
text=("CORS header `Access-Control-Allow-Methods`"
" set to a wild character,it is a good"
" practice to give a white list of allowed"
" methods."))
)
if 'Access-Control-Allow-Headers' in self.resp.headers:
if self.resp.headers['Access-Control-Allow-Headers'] == "*":
self.register_issue(
Issue(test="CORS_HEADER",
severity="Low",
confidence="High",
text=("CORS header `Access-Control-Allow-Headers`"
" set to a wild character,it is a good"
" practice to give a white list of allowed"
" headers"
)
)
syntribos.Issue(
test="CORS_HEADER",
severity=syntribos.LOW,
confidence=syntribos.HIGH,
text=("CORS header `Access-Control-Allow-Headers`"
" set to a wild character,it is a good"
" practice to give a white list of allowed"
" headers"))
)

View File

@ -16,9 +16,9 @@ import re
from six.moves.urllib.parse import urlparse
import syntribos
from syntribos.clients.http import client
from syntribos.clients.http import parser
from syntribos.issue import Issue
from syntribos.tests import base
@ -47,11 +47,10 @@ class SSLTestCase(base.BaseTestCase):
if re.search(regex, response_text):
self.register_issue(
Issue(test="SSL_ERROR",
severity="Medium",
confidence="High",
text=("Make sure that all the returned endpoint URIs"
" use 'https://' and not 'http://'"
)
)
syntribos.Issue(
test="SSL_ERROR",
severity=syntribos.MEDIUM,
confidence=syntribos.HIGH,
text=("Make sure that all the returned endpoint URIs"
" use 'https://' and not 'http://'"))
)