def check(self, key: str, value: str, filepath: Path, foundlines: List[int]) -> Secret: matrix = {"key": key, "value": value} checks = { "minlen": self.check_minlen, "regex": self.check_regex, "isBase64": self.check_isBase64, "isAscii": self.check_isAscii, "isUri": self.check_isUri, "isLuhn": self.check_isLuhn, } if not filepath.is_file(): return # Only check files for rule_id, rule in self.rules.items(): rule_matched = True if self.ruleslist != ["all"]: if rule_id not in self.ruleslist: continue # Only report configured rules else: if rule["severity"] == "INFO": continue # Don't report INFO on all rules if "similar" in rule: if self.check_similar(rule, key, value): rule_matched = False for check_idx, check_function in checks.items(): if not rule_matched: break for mkey, mvalue in matrix.items(): if mkey not in rule: continue if check_idx not in rule[mkey]: continue if not check_function(rule, mkey, mvalue): rule_matched = False break if not rule_matched: continue return Secret( filepath.as_posix(), find_line_number(filepath, key, value, foundlines), key, value, self.rules[rule_id]["message"], self.rules[rule_id]["severity"], )
def check(self, key, value, filepath): matrix = {"key": key, "value": value} checks = { "minlen": self.check_minlen, "regex": self.check_regex, "isBase64": self.check_isBase64, "isAscii": self.check_isAscii, "isUri": self.check_isUri, } for rule_id, rule in self.rules.items(): rule_matched = True if rule["severity"] == "INFO": continue if "similar" in rule: if self.check_similar(rule, key, value): rule_matched = False for check_idx, check_function in checks.items(): if not rule_matched: break for mkey, mvalue in matrix.items(): if mkey not in rule: continue if check_idx not in rule[mkey]: continue if not check_function(rule, mkey, mvalue): rule_matched = False break if not rule_matched: continue return Secret( filepath.as_posix(), find_line_number(filepath, key, value), key, value, self.rules[rule_id]["message"], self.rules[rule_id]["severity"], )
def check(self, key, value, filepath): def decode_if_base64(mkey, mvalue): if "isBase64" in mkey: if mkey["isBase64"]: mvalue = b64decode(mvalue) return mvalue def is_ascii(data): if not isinstance(data, str): return False for ch in data: if ord(ch) not in range(32, 127): return False return True def check_minlen(rule, mkey, mvalue): return len(mvalue) >= int(rule[mkey]["minlen"]) def check_regex(rule, mkey, mvalue): return rule[mkey]["regex"].match(mvalue) def check_isBase64(rule, mkey, mvalue): return rule[mkey]["isBase64"] == self.match("base64", mvalue) def check_isAscii(rule, mkey, mvalue): mvalue = decode_if_base64(mkey, mvalue) return is_ascii(mvalue) def check_isUri(rule, mkey, mvalue): mvalue = decode_if_base64(mkey, mvalue) return rule[mkey]["isUri"] == self.match("uri", mvalue) def check_similar(rule, key, value): return similar_strings(key, value) < rule["similar"] matrix = {"key": key, "value": value} checks = { "minlen": check_minlen, "regex": check_regex, "isBase64": check_isBase64, "isAscii": check_isAscii, "isUri": check_isUri, } for rule_id, rule in self.rules.items(): rule_matched = True if rule["severity"] == "INFO": continue if "similar" in rule: if similar_strings(key, value) >= rule["similar"]: rule_matched = False for check_idx, check_function in checks.items(): if not rule_matched: break for mkey, mvalue in matrix.items(): if mkey not in rule: continue if check_idx not in rule[mkey]: continue if not check_function(rule, mkey, mvalue): rule_matched = False break if not rule_matched: continue return Secret( filepath.as_posix(), find_line_number(filepath, key, value), key, value, self.rules[rule_id]["message"], self.rules[rule_id]["severity"], )
def test_find_line_number_single(src, key, value, expectation): assert find_line_number(FIXTURE_PATH.joinpath(src), key, value, []) == expectation