Пример #1
0
    def __validate_must_avoid(self, rule, config, header, directive):
        """
        Verify specified values do not exist in loaded headers.

        :param rule: Name of rule to validate
        :param config: Configuration rule-set to use
        :param header: Name of header
        :param directive: Name of directive (optional)
        """

        try:
            config['Must-Avoid'] = [item.lower() for item in config['Must-Avoid']]
            for avoid in config['Must-Avoid']:
                if directive:
                    rule_value = _to_dict(self.headers[header.lower()], ';', ' ')[rule]
                else:
                    rule_value = self.headers[rule]

                if avoid in rule_value and rule not in self.anomalies:
                    if rule == 'content-security-policy':
                        policy = _to_dict(self.headers[header.lower()], ';', ' ')
                        directive = list(policy.keys())[list(policy.values()).index(avoid)]
                    self.__add_report_item(severity='medium', rule=rule, error_type=5, header=header,
                                           directive=directive, avoid=config['Must-Avoid'], value=avoid)
        except KeyError:
            pass
Пример #2
0
    def __validate_must_contain(self, rule, config, header, directive):
        """
        Verify the provided header contains certain params.

        :param rule: Name of rule to validate
        :param config: Configuration rule-set to use
        :param header: Name of header
        :param directive: Name of directive (optional)
        """

        try:
            if 'Must-Contain-One' in config:
                config['Must-Contain-One'] = [item.lower() for item in config['Must-Contain-One']]
                contain = False
                if directive:
                    policy = _to_dict(self.headers[header.lower()], ';', ' ')
                    values = policy[rule].split(' ')
                else:
                    policy = self.headers[rule]
                    values = policy.split(self.delimiter)
                for value in values:
                    value = value.lstrip()
                    if value in config['Must-Contain-One']:
                        contain = True
                        break

                if not contain:
                    self.__add_report_item(severity='high', rule=rule, error_type=6, header=header, directive=directive,
                                           expected=config['Must-Contain-One'], value=config['Must-Contain-One'])

            elif 'Must-Contain' in config:
                config['Must-Contain'] = [item.lower() for item in config['Must-Contain']]
                if rule == 'set-cookie':
                    for cookie in self.headers[rule]:
                        for contain in config['Must-Contain']:
                            if contain not in cookie:
                                if contain == 'secure':
                                    severity = 'high'
                                else:
                                    severity = 'medium'
                                self.__add_report_item(
                                    severity=severity, rule=rule, error_type=4, header=header,
                                    expected=config['Must-Contain'], value=contain, cookie=cookie)
                else:
                    if directive:
                        rule_value = _to_dict(self.headers[header.lower()], ';', ' ')[rule]
                    else:
                        rule_value = self.headers[rule]
                    for contain in config['Must-Contain']:
                        if contain not in rule_value and rule not in self.anomalies:
                            self.__add_report_item(severity='medium', rule=rule, error_type=4, header=header,
                                                   directive=directive, expected=config['Must-Contain'], value=contain)
        except KeyError:
            pass
Пример #3
0
    def __validate_rule_and_value(self, rule, expected_value, header, directive):
        """
        Verify headers content matches provided config.

        :param rule: Name of rule to validate
        :param expected_value: Expected value of header.
        :param header: Name of header
        :param directive: Name of directive (optional)
        :return:
        """
        expected_value_list = [str(item).lower() for item in expected_value]
        if len(expected_value_list) == 1:
            expected_value_list = [item.strip(' ') for item in expected_value_list[0].split(self.delimiter)]

        if directive:
            error_type = 7
            rule_value = _to_dict(self.headers[header.lower()], ';', ' ')
        else:
            error_type = 1
            rule_value = self.headers

        if rule not in rule_value:
            self.__add_report_item(severity='high', rule=rule, error_type=error_type, header=header,
                                   directive=directive, expected=expected_value_list)
        else:
            rule_list = [item.strip(' ') for item in rule_value[rule.lower()].split(self.delimiter)]
            if not all(elem in expected_value_list for elem in rule_list):
                self.__add_report_item(severity='high', rule=rule, error_type=3, header=header, directive=directive,
                                       expected=expected_value_list, value=rule_value[rule])
Пример #4
0
    def __validate_must_avoid(self, config, header, directive):
        """
        Verify specified values do not exist in loaded headers.

        :param config: Configuration rule-set to use
        :param header: Name of header
        :param directive: Name of directive (optional)
        """
        if directive:
            rule = directive
            header_value = _to_dict(self.headers[header], ';', ' ')[rule]
        else:
            rule = header
            header_value = self.headers[rule]

        config['Must-Avoid'] = [item.lower() for item in config['Must-Avoid']]

        for avoid_value in config['Must-Avoid']:
            if avoid_value in header_value and rule not in self.anomalies:
                if rule.lower() == 'content-security-policy':
                    policy = _to_dict(self.headers[header], ';', ' ')
                    non_compliant_values = [
                        item for item in list(policy.values())
                        if avoid_value in item
                    ]
                    indices = [
                        list(policy.values()).index(item)
                        for item in non_compliant_values
                    ]
                    for index in indices:
                        self.__add_report_item(severity='medium',
                                               error_type=5,
                                               header=header,
                                               directive=list(
                                                   policy.keys())[index],
                                               avoid=config['Must-Avoid'],
                                               value=avoid_value)
                else:
                    self.__add_report_item(severity='medium',
                                           error_type=5,
                                           header=header,
                                           directive=directive,
                                           avoid=config['Must-Avoid'],
                                           value=avoid_value)
Пример #5
0
    def __add_report_item(self,
                          severity,
                          error_type,
                          header,
                          directive=None,
                          expected=None,
                          avoid=None,
                          value='',
                          cookie=''):
        """
        Add a entry to report.

        :param severity: [low, medium, high]
        :type severity: str
        :param error_type: [1...6] related to error_types
        :type error_type: int
        :param expected: Expected value of header
        :param avoid: Avoid value of header
        :param value: Current value of header
        :param cookie: Value of cookie (if applicable)
        """
        if directive:
            error = {
                'rule': header + ' - ' + directive,
                'severity': severity,
                'message': self.error_types[error_type]
            }
        else:
            error = {
                'rule': header,
                'severity': severity,
                'message': self.error_types[error_type]
            }

        if expected:
            error['expected'] = expected
            error['delimiter'] = self.delimiter
        if avoid:
            error['avoid'] = avoid
            error['delimiter'] = self.delimiter

        if error_type == 3:
            error['value'] = value
        elif error_type in (4, 5, 6):
            if header.lower() == 'set-cookie':
                error['value'] = cookie
            else:
                if directive:
                    error['value'] = _to_dict(self.headers[header], ';',
                                              ' ')[directive].strip('\'')
                else:
                    error['value'] = self.headers[header]
            error['anomaly'] = value
        self.report.append(error)
Пример #6
0
    def __validate_exists(self, rule, header, directive):
        """
        Verify specified rule exists in loaded headers.

        :param rule: Name of rule to validate
        :param header: Name of header
        :param directive: Name of directive (optional)
        """
        if directive:
            error_type = 7
            headers = _to_dict(self.headers[header.lower()], ';', ' ')
        else:
            error_type = 1
            headers = self.headers

        if rule not in headers:
            self.__add_report_item(severity='high', rule=rule, error_type=error_type, header=header,
                                   directive=directive)
Пример #7
0
    def __validate_not_exists(self, header, directive):
        """
        Verify specified rule does not exist in loaded headers.

        :param header: Name of header
        :param directive: Name of directive (optional)
        """

        if directive:
            rule = directive
            headers = _to_dict(self.headers[header], ';', ' ')
        else:
            rule = header
            headers = self.headers

        if rule in headers:
            self.__add_report_item(severity='high',
                                   error_type=8 if directive else 2,
                                   header=header,
                                   directive=directive)
Пример #8
0
    def __validate_exists(self, header, directive):
        """
        Verify specified rule exists in loaded headers.

        :param header: Name of header
        :param directive: Name of directive (optional)
        """
        if directive:
            rule = directive
            headers = _to_dict(self.headers[header], ';', ' ')
        else:
            rule = header
            headers = self.headers

        if rule not in headers:
            self.__add_report_item(severity='high',
                                   error_type=7 if directive else 1,
                                   header=header,
                                   directive=directive)

        return rule in headers  # Return value to prevent subsequent avoid/contain checks if the header is not present
Пример #9
0
    def __validate_must_contain(self, config, header, directive):
        """
        Verify the provided header contains certain params.

        :param config: Configuration rule-set to use
        :param header: Name of header
        :param directive: Name of directive (optional)
        """
        if directive:
            rule = directive
            header_value = _to_dict(self.headers[header], ';', ' ')[rule]
        else:
            rule = header
            header_value = self.headers[rule]

        if 'Must-Contain-One' in config:
            config['Must-Contain-One'] = [
                item.lower() for item in config['Must-Contain-One']
            ]
            contain_values = header_value.split(
                ' ') if directive else header_value.split(self.delimiter)
            does_contain = False

            for contain_value in contain_values:
                contain_value = contain_value.lstrip()
                if contain_value in config['Must-Contain-One']:
                    does_contain = True
                    break
            if not does_contain:
                self.__add_report_item(severity='high',
                                       error_type=6,
                                       header=header,
                                       directive=directive,
                                       expected=config['Must-Contain-One'],
                                       value=config['Must-Contain-One'])

        elif 'Must-Contain' in config:
            config['Must-Contain'] = [
                item.lower() for item in config['Must-Contain']
            ]
            if header.lower() == 'set-cookie':
                for cookie in self.headers[header]:
                    for contain_value in config['Must-Contain']:
                        if contain_value not in cookie:
                            self.__add_report_item(
                                severity='high'
                                if contain_value == 'secure' else 'medium',
                                error_type=4,
                                header=header,
                                expected=config['Must-Contain'],
                                value=contain_value,
                                cookie=cookie)
            else:
                for contain_value in config['Must-Contain']:
                    if contain_value not in header_value and rule not in self.anomalies:
                        self.__add_report_item(severity='medium',
                                               error_type=4,
                                               header=header,
                                               directive=directive,
                                               expected=config['Must-Contain'],
                                               value=contain_value)