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
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
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])
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)
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)
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)
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)
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
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)