Merge "Added string presence check"
This commit is contained in:
commit
a42cf2895b
|
@ -15,5 +15,6 @@
|
|||
from syntribos.checks.length import max_body_length as max_length
|
||||
from syntribos.checks.length import percentage_difference as length_diff
|
||||
from syntribos.checks.ssl import https_check as https_check
|
||||
from syntribos.checks.string import has_string as has_string
|
||||
from syntribos.checks.time import percentage_difference as time_diff
|
||||
from syntribos.checks.time import absolute_time as time_abs
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright 2016 Intel
|
||||
#
|
||||
# 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 syntribos.signal
|
||||
|
||||
|
||||
def has_string(test):
|
||||
"""Checks if the response consists of any failure strings
|
||||
|
||||
:returns: syntribos.signal.SynSignal
|
||||
"""
|
||||
|
||||
slug = "FAILURE_KEYS_PRESENT"
|
||||
data = {
|
||||
"req": test.test_resp.request,
|
||||
"resp": test.test_resp,
|
||||
"failure_strings": []
|
||||
}
|
||||
|
||||
failure_keys = test.failure_keys
|
||||
if failure_keys:
|
||||
data["failure_strings"] = [key for key in failure_keys
|
||||
if key in test.test_resp.content]
|
||||
|
||||
if len(data["failure_strings"]) > 0:
|
||||
keys = "\n".join(map(str, data["failure_strings"]))
|
||||
text = "Failure strings present " + keys
|
||||
return syntribos.signal.SynSignal(check_name="has_string", text=text,
|
||||
slug=slug, data=data, strength=1.0)
|
|
@ -43,37 +43,6 @@ class BaseFuzzTestCase(base.BaseTestCase):
|
|||
parser=syntribos.tests.fuzz.datagen.FuzzParser
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def data_driven_failure_cases(cls):
|
||||
"""Checks if response contains known bad strings
|
||||
|
||||
:returns: a list of strings that show up in the response that are also
|
||||
defined in cls.failure_strings.
|
||||
failed_strings = []
|
||||
"""
|
||||
failed_strings = []
|
||||
if cls.failure_keys is None:
|
||||
return []
|
||||
for line in cls.failure_keys:
|
||||
if line in cls.test_resp.content:
|
||||
failed_strings.append(line)
|
||||
return failed_strings
|
||||
|
||||
@classmethod
|
||||
def data_driven_pass_cases(cls):
|
||||
"""Checks if response contains expected strings
|
||||
|
||||
:returns: a list of assertions that fail if the response doesn't
|
||||
contain a string defined in cls.success_keys as a string expected in
|
||||
the response.
|
||||
"""
|
||||
if cls.success_keys is None:
|
||||
return True
|
||||
for s in cls.success_keys:
|
||||
if s in cls.test_resp.content:
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""being used as a setup test not."""
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import syntribos
|
||||
from syntribos.checks import has_string as has_string
|
||||
from syntribos.checks import time_diff as time_diff
|
||||
from syntribos.tests.fuzz import base_fuzz
|
||||
|
||||
|
@ -38,17 +39,20 @@ class BufferOverflowBody(base_fuzz.BaseFuzzTestCase):
|
|||
|
||||
def test_case(self):
|
||||
self.test_default_issues()
|
||||
failed_strings = self.data_driven_failure_cases()
|
||||
if failed_strings:
|
||||
self.test_signals.register(has_string(self))
|
||||
if "FAILURE_KEYS_PRESENT" in self.test_signals:
|
||||
failed_strings = self.test_signals.find(
|
||||
slugs="FAILURE_KEYS_PRESENT")[0].data["failed_strings"]
|
||||
self.register_issue(
|
||||
defect_type="bof_strings",
|
||||
severity=syntribos.MEDIUM,
|
||||
confidence=syntribos.LOW,
|
||||
description=("The string(s): \'{0}\', known to be commonly "
|
||||
description=("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))
|
||||
|
||||
self.diff_signals.register(time_diff(self))
|
||||
if "TIME_DIFF_OVER" in self.diff_signals:
|
||||
self.register_issue(
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import syntribos
|
||||
from syntribos.checks import has_string as has_string
|
||||
from syntribos.checks import time_diff as time_diff
|
||||
from syntribos.tests.fuzz import base_fuzz
|
||||
|
||||
|
@ -29,8 +30,10 @@ class CommandInjectionBody(base_fuzz.BaseFuzzTestCase):
|
|||
|
||||
def test_case(self):
|
||||
self.test_default_issues()
|
||||
failed_strings = self.data_driven_failure_cases()
|
||||
if failed_strings:
|
||||
self.test_signals.register(has_string(self))
|
||||
if "FAILURE_KEYS_PRESENT" in self.test_signals:
|
||||
failed_strings = self.test_signals.find(
|
||||
slugs="FAILURE_KEYS_PRESENT")[0].data["failed_strings"]
|
||||
self.register_issue(
|
||||
defect_type="command_injection",
|
||||
severity=syntribos.HIGH,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import syntribos
|
||||
from syntribos.checks import has_string as has_string
|
||||
from syntribos.checks import time_diff as time_diff
|
||||
from syntribos.tests.fuzz import base_fuzz
|
||||
|
||||
|
@ -42,13 +43,15 @@ class SQLInjectionBody(base_fuzz.BaseFuzzTestCase):
|
|||
|
||||
def test_case(self):
|
||||
self.test_default_issues()
|
||||
failed_strings = self.data_driven_failure_cases()
|
||||
if failed_strings:
|
||||
self.test_signals.register(has_string(self))
|
||||
if "FAILURE_KEYS_PRESENT" in self.test_signals:
|
||||
failed_strings = self.test_signals.find(
|
||||
slugs="FAILURE_KEYS_PRESENT")[0].data["failed_strings"]
|
||||
self.register_issue(
|
||||
defect_type="sql_strings",
|
||||
severity=syntribos.MEDIUM,
|
||||
confidence=syntribos.LOW,
|
||||
description=("The string(s): \'{0}\', known to be commonly "
|
||||
description=("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 "
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
from oslo_config import cfg
|
||||
|
||||
import syntribos
|
||||
from syntribos.checks import has_string as has_string
|
||||
from syntribos.checks import time_diff as time_diff
|
||||
from syntribos.tests.fuzz import base_fuzz
|
||||
import syntribos.tests.fuzz.datagen
|
||||
|
@ -79,13 +80,15 @@ class XMLExternalEntityBody(base_fuzz.BaseFuzzTestCase):
|
|||
|
||||
def test_case(self):
|
||||
self.test_default_issues()
|
||||
failed_strings = self.data_driven_failure_cases()
|
||||
if failed_strings:
|
||||
self.test_signals.register(has_string(self))
|
||||
if "FAILURE_KEYS_PRESENT" in self.test_signals:
|
||||
failed_strings = self.test_signals.find(
|
||||
slugs="FAILURE_KEYS_PRESENT")[0].data["failed_strings"]
|
||||
self.register_issue(
|
||||
defect_type="xml_strings",
|
||||
severity=syntribos.MEDIUM,
|
||||
confidence=syntribos.LOW,
|
||||
description=("The string(s): \'{0}\', known to be commonly "
|
||||
description=("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 "
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import syntribos
|
||||
from syntribos.checks import has_string as has_string
|
||||
from syntribos.tests.fuzz import base_fuzz
|
||||
|
||||
|
||||
|
@ -23,7 +24,8 @@ class XSSBody(base_fuzz.BaseFuzzTestCase):
|
|||
def test_case(self):
|
||||
self.test_default_issues()
|
||||
self.failure_keys = self._get_strings()
|
||||
failed_strings = self.data_driven_failure_cases()
|
||||
self.test_signals.register(has_string(self))
|
||||
|
||||
if 'content-type' in self.init_req.headers:
|
||||
content_type = self.init_req.headers['content-type']
|
||||
if 'html' in content_type:
|
||||
|
@ -32,12 +34,14 @@ class XSSBody(base_fuzz.BaseFuzzTestCase):
|
|||
sev = syntribos.LOW
|
||||
else:
|
||||
sev = syntribos.LOW
|
||||
if failed_strings:
|
||||
if "FAILURE_KEYS_PRESENT" in self.test_signals:
|
||||
failed_strings = self.test_signals.find(
|
||||
slugs="FAILURE_KEYS_PRESENT")[0].data["failed_strings"]
|
||||
self.register_issue(
|
||||
defect_type="xss_strings",
|
||||
severity=sev,
|
||||
confidence=syntribos.LOW,
|
||||
description=("The string(s): \'{0}\', known to be commonly "
|
||||
description=("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 "
|
||||
|
|
Loading…
Reference in New Issue