Exemple #1
0
 def test_matching(self):
     """Creates SH with signal, attempts to retrieve w/ search."""
     SH = SignalHolder(self.test_signal)
     matching = SH.find(slugs=self.test_signal.slug)
     self.assertIsInstance(matching, SignalHolder)
     self.assertEqual(1, len(matching))
     self._assert_same_signal(self.test_signal, matching[0])
Exemple #2
0
 def test_matching(self):
     """Creates SH with signal, attempts to retrieve w/ search."""
     SH = SignalHolder(self.test_signal)
     matching = SH.find(slugs=self.test_signal.slug)
     self.assertIsInstance(matching, SignalHolder)
     self.assertEqual(1, len(matching))
     self._assert_same_signal(self.test_signal, matching[0])
Exemple #3
0
 def test_register_duplicate_signal(self):
     """Creates empty SH, tries registering dupe signal."""
     SH = SignalHolder()
     SH.register(self.test_signal)
     SH.register(self.test_signal)
     self.assertEqual(1, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])
Exemple #4
0
 def test_register_duplicate_signal(self):
     """Creates empty SH, tries registering dupe signal."""
     SH = SignalHolder()
     SH.register(self.test_signal)
     SH.register(self.test_signal)
     self.assertEqual(1, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])
Exemple #5
0
 def test_register_signal_list(self):
     """Creates empty SH, registers signal list, checks for presence."""
     SH = SignalHolder()
     SH.register([self.test_signal, self.test_signal2])
     self.assertEqual(2, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])
     self._assert_same_signal(self.test_signal2, SH[1])
Exemple #6
0
 def test_register_signal_list(self):
     """Creates empty SH, registers signal list, checks for presence."""
     SH = SignalHolder()
     SH.register([self.test_signal, self.test_signal2])
     self.assertEqual(2, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])
     self._assert_same_signal(self.test_signal2, SH[1])
Exemple #7
0
 def test_register_SH(self):
     """Creates empty SH, registers SH w/ signals, checks for presence."""
     SH = SignalHolder([self.test_signal, self.test_signal2])
     SH2 = SignalHolder()
     SH2.register(SH)
     self.assertEqual(2, len(SH2))
     self._assert_same_signal(self.test_signal, SH2[0])
     self._assert_same_signal(self.test_signal2, SH2[1])
Exemple #8
0
 def test_register_SH(self):
     """Creates empty SH, registers SH w/ signals, checks for presence."""
     SH = SignalHolder([self.test_signal, self.test_signal2])
     SH2 = SignalHolder()
     SH2.register(SH)
     self.assertEqual(2, len(SH2))
     self._assert_same_signal(self.test_signal, SH2[0])
     self._assert_same_signal(self.test_signal2, SH2[1])
Exemple #9
0
 def test_init_SH(self):
     """Creates SignalHolder with SH of signals, checks for presence."""
     SH = SignalHolder([self.test_signal, self.test_signal2])
     SH2 = SignalHolder(SH)
     self.assertEqual(2, len(SH))
     self.assertEqual(2, len(SH2))
     self._assert_same_signal(self.test_signal, SH2[0])
     self._assert_same_signal(self.test_signal2, SH2[1])
Exemple #10
0
 def test_is_equal(self):
     """Tests 'equality' of two SignalHolders."""
     SH1 = SignalHolder(self.test_signal)
     SH2 = SignalHolder(self.test_signal)
     self.assertEqual(SH1, SH2)
     self.assertEqual(SH1, SH2)
     SH2 = SignalHolder(self.test_signal2)
     self.assertNotEqual(SH1, SH2)
     self.assertNotEqual(SH2, SH1)
Exemple #11
0
    def test_SH_repr(self):
        """Creates a SH with signal, checks __repr__ value."""
        SH = SignalHolder(self.test_signal)
        self.assertEqual(1, len(SH))
        self.assertEqual('["TEST_SIGNAL"]', str(SH))

        SH.register(self.test_signal2)
        self.assertEqual(2, len(SH))
        self.assertEqual('["TEST_SIGNAL", "TEST_SIGNAL2"]', str(SH))
Exemple #12
0
    def test_SH_repr(self):
        """Creates a SH with signal, checks __repr__ value."""
        SH = SignalHolder(self.test_signal)
        self.assertEqual(1, len(SH))
        self.assertEqual('["TEST_SIGNAL"]', str(SH))

        SH.register(self.test_signal2)
        self.assertEqual(2, len(SH))
        self.assertEqual('["TEST_SIGNAL", "TEST_SIGNAL2"]', str(SH))
Exemple #13
0
 def test_compare(self):
     """Tests 'compare' method to see if two SignalHolders differ."""
     SH1 = SignalHolder(self.test_signal)
     SH2 = SignalHolder(self.test_signal)
     data = {"is_diff": False,
             "sh1_len": 1,
             "sh2_len": 1,
             "sh1_not_in_sh2": SignalHolder(),
             "sh2_not_in_sh1": SignalHolder()}
     self.assertEqual(data, SH1.compare(SH2))
     SH2 = SignalHolder(self.test_signal2)
     self.assertNotEqual(data, SH1.compare(SH2))
Exemple #14
0
 def test_compare(self):
     """Tests 'compare' method to see if two SignalHolders differ."""
     SH1 = SignalHolder(self.test_signal)
     SH2 = SignalHolder(self.test_signal)
     data = {
         "is_diff": False,
         "sh1_len": 1,
         "sh2_len": 1,
         "sh1_not_in_sh2": SignalHolder(),
         "sh2_not_in_sh1": SignalHolder()
     }
     self.assertEqual(data, SH1.compare(SH2))
     SH2 = SignalHolder(self.test_signal2)
     self.assertNotEqual(data, SH1.compare(SH2))
Exemple #15
0
 def test_register_0_strength_signal(self):
     """Attempts to register a signal w/ strength = 0."""
     SH = SignalHolder()
     SH.register(self.test_signal_0_strength)
     self.assertEqual(0, len(SH))
Exemple #16
0
 def test_register_0_strength_signal(self):
     """Attempts to register a signal w/ strength = 0."""
     SH = SignalHolder()
     SH.register(self.test_signal_0_strength)
     self.assertEqual(0, len(SH))
Exemple #17
0
 def test_contains_tag(self):
     """Creates SH with a signal, checks 'contains' idiom for tags."""
     SH = SignalHolder(self.test_signal)
     self.assertEqual(len(SH), 1)
     self.assertIn(self.test_signal.slug, SH)
Exemple #18
0
 def test_register_one_signal(self):
     """Creates empty SH, registers 1 signal, checks for presence."""
     SH = SignalHolder()
     SH.register(self.test_signal)
     self.assertEqual(1, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])
Exemple #19
0
 def test_register_one_signal(self):
     """Creates empty SH, registers 1 signal, checks for presence."""
     SH = SignalHolder()
     SH.register(self.test_signal)
     self.assertEqual(1, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])
Exemple #20
0
 def test_init_signal_list(self):
     """Creates SignalHolder with list of signals, checks for presence."""
     SH = SignalHolder([self.test_signal, self.test_signal2])
     self.assertEqual(2, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])
     self._assert_same_signal(self.test_signal2, SH[1])
Exemple #21
0
class BaseTestCase(unittest.TestCase):
    """Base class for building new tests

    :attribute str test_name: A name like ``XML_EXTERNAL_ENTITY_BODY``,
        containing the test type and the portion of the request template being
        tested
    :attribute list failures: A collection of "failures" raised by tests
    :attribute bool dead: Flip this if one of the requests doesn't return a
        response object
    :attribute client: HTTP client to be used by the test
    :attribute init_req: Initial request (loaded from request template)
    :attribute init_resp: Response to the initial request
    :attribute test_req: Request sent by the test for analysis
    :attribute test_resp: Response to the test request
    :attribute init_signals: Holder for signals on `init_req`
    :attribute test_signals: Holder for signals on `test_req`
    :attribute diff_signals: Holder for signals between `init_req` and
        `test_req`
    """

    test_name = None
    failures = []
    errors = []
    dead = False
    client = client()

    init_req = None
    init_resp = None
    test_req = None
    test_resp = None

    init_signals = SignalHolder()
    test_signals = SignalHolder()
    diff_signals = SignalHolder()

    @classmethod
    def register_opts(cls):
        pass

    @classmethod
    def get_test_cases(cls, filename, file_content, meta_vars):
        """Returns tests for given TestCase class (overwritten by children)."""
        yield cls

    @classmethod
    def create_init_request(cls, filename, file_content, meta_vars):
        """Parses template and creates init request object

        This method does not send the initial request, instead, it only creates
        the object for use in the debug test

        :param str filename: name of template file
        :param str file_content: content of template file as string
        """
        request_obj = parser.create_request(file_content,
                                            CONF.syntribos.endpoint, meta_vars)
        cls.init_req = request_obj
        cls.init_resp = None
        cls.init_signals = None
        cls.template_path = filename

    @classmethod
    def send_init_request(cls, filename, file_content, meta_vars):
        """Parses template, creates init request object, and sends init request

        This method sends the initial request, which is the request created
        after parsing the template file. This request will not be modified
        any further by the test cases themselves.

        :param str filename: name of template file
        :param str file_content: content of template file as string
        """
        if not cls.init_req:
            cls.init_req = parser.create_request(file_content,
                                                 CONF.syntribos.endpoint,
                                                 meta_vars)
        prepared_copy = cls.init_req.get_prepared_copy()
        cls.prepared_init_req = prepared_copy
        cls.init_resp, cls.init_signals = cls.client.send_request(
            prepared_copy)
        if cls.init_resp is not None:
            # Get the computed body and add it to our RequestObject
            # TODO(cneill): Figure out a better way to handle this discrepancy
            cls.init_req.body = cls.init_resp.request.body
        else:
            cls.dead = True

    @classmethod
    def extend_class(cls, new_name, kwargs):
        """Creates an extension for the class

        Each TestCase class created is added to the `test_table`, which is then
        read in by the test runner as the master list of tests to be run.

        :param str new_name: Name of new class to be created
        :param dict kwargs: Keyword arguments to pass to the new class
        :rtype: class
        :returns: A TestCase class extending :class:`BaseTestCase`
        """

        new_name = replace_invalid_characters(new_name)
        if not isinstance(kwargs, dict):
            raise Exception("kwargs must be a dictionary")
        new_cls = type(new_name, (cls, ), kwargs)
        new_cls.__module__ = cls.__module__
        return new_cls

    @classmethod
    def tearDownClass(cls):
        super(BaseTestCase, cls).tearDownClass()
        if not cls.failures:
            if "EXCEPTION_RAISED" in cls.test_signals:
                sig = cls.test_signals.find(tags="EXCEPTION_RAISED")[0]
                exc_name = type(sig.data["exception"]).__name__
                if ("CONNECTION_FAIL" in sig.tags):
                    six.raise_from(
                        FatalHTTPError(
                            "The remote target has forcibly closed the connection "
                            "with Syntribos and resulted in exception '{}'. This "
                            "could potentially mean that a fatal error was "
                            "encountered within the target application or server"
                            " itself.".format(exc_name)),
                        sig.data["exception"])
                else:
                    raise sig.data["exception"]

    @classmethod
    def tearDown(cls):
        get_slugs = [sig.slug for sig in cls.test_signals]
        get_checks = [sig.check_name for sig in cls.test_signals]
        test_signals_used = "Signals: " + str(get_slugs)
        LOG.debug(test_signals_used)
        test_checks_used = "Checks used: " + str(get_checks)
        LOG.debug(test_checks_used)

    def run_test_case(self):
        """This kicks off the test(s) for a given TestCase class

        After running the tests, an `AssertionError` is raised if any tests
        were added to self.failures.

        :raises: :exc:`AssertionError`
        """
        if not self.dead:
            try:
                self.test_case()
            except Exception as e:
                self.errors += e
                raise
            if self.failures:
                raise AssertionError

    def test_case(self):
        """This method is overwritten by individual TestCase classes

        It represents the actual test that is called in :func:`run_test_case`,
        and handles populating `self.failures`
        """
        pass

    def register_issue(self, defect_type, severity, confidence, description):
        """Adds an issue to the test's list of issues

        Creates a :class:`syntribos.issue.Issue` object, with given function
        parameters as instances variables, and registers the issue as a
        failure and associates the test's metadata to it.

        :param defect_type: The type of vulnerability that Syntribos believes
        it has found. This may be something like 500 error or DoS, regardless
        tof whathe Test Type is.
        :param severity: "Low", "Medium", or "High", depending on the defect
        :param description: Description of the defect
        :param confidence: The confidence of the defect
        :returns: new issue object with metadata associated
        :rtype: Issue
        """

        issue = syntribos.Issue(defect_type=defect_type,
                                severity=severity,
                                confidence=confidence,
                                description=description)

        issue.request = self.test_req if self.test_req else self.init_req
        issue.response = self.test_resp if self.test_resp else self.init_resp
        issue.template_path = self.template_path
        issue.parameter_location = self.parameter_location
        issue.test_type = self.test_name
        url_components = urlparse(self.init_resp.url)
        issue.target = url_components.netloc
        issue.path = url_components.path
        issue.init_signals = self.init_signals
        issue.test_signals = self.test_signals
        issue.diff_signals = self.diff_signals

        self.failures.append(issue)

        return issue
Exemple #22
0
 def test_init_one_signal(self):
     """Creates SignalHolder with 1 signal, checks for presence."""
     SH = SignalHolder(self.test_signal)
     self.assertEqual(1, len(SH))
     self._assert_same_signal(self.test_signal, SH[0])