credsweeper 1.11.2__py3-none-any.whl → 1.11.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of credsweeper might be problematic. Click here for more details.

Files changed (55) hide show
  1. credsweeper/__init__.py +1 -1
  2. credsweeper/__main__.py +6 -4
  3. credsweeper/app.py +7 -3
  4. credsweeper/common/keyword_pattern.py +15 -9
  5. credsweeper/common/morpheme_checklist.txt +4 -2
  6. credsweeper/credentials/line_data.py +14 -10
  7. credsweeper/deep_scanner/abstract_scanner.py +10 -1
  8. credsweeper/deep_scanner/deep_scanner.py +19 -8
  9. credsweeper/deep_scanner/docx_scanner.py +1 -1
  10. credsweeper/deep_scanner/encoder_scanner.py +2 -2
  11. credsweeper/deep_scanner/html_scanner.py +3 -3
  12. credsweeper/deep_scanner/jks_scanner.py +2 -4
  13. credsweeper/deep_scanner/lang_scanner.py +2 -2
  14. credsweeper/deep_scanner/lzma_scanner.py +40 -0
  15. credsweeper/deep_scanner/pkcs12_scanner.py +3 -5
  16. credsweeper/deep_scanner/xml_scanner.py +2 -2
  17. credsweeper/file_handler/data_content_provider.py +21 -12
  18. credsweeper/filters/value_array_dictionary_check.py +3 -1
  19. credsweeper/filters/value_azure_token_check.py +1 -2
  20. credsweeper/filters/value_base64_part_check.py +30 -21
  21. credsweeper/filters/value_discord_bot_check.py +1 -2
  22. credsweeper/filters/value_entropy_base32_check.py +11 -31
  23. credsweeper/filters/value_entropy_base36_check.py +11 -34
  24. credsweeper/filters/value_entropy_base64_check.py +19 -48
  25. credsweeper/filters/value_entropy_base_check.py +37 -0
  26. credsweeper/filters/value_file_path_check.py +1 -1
  27. credsweeper/filters/value_hex_number_check.py +3 -3
  28. credsweeper/filters/value_json_web_token_check.py +4 -5
  29. credsweeper/filters/value_string_type_check.py +11 -3
  30. credsweeper/filters/value_token_base32_check.py +0 -4
  31. credsweeper/filters/value_token_base36_check.py +0 -4
  32. credsweeper/filters/value_token_base64_check.py +0 -4
  33. credsweeper/filters/value_token_check.py +1 -1
  34. credsweeper/ml_model/features/file_extension.py +1 -1
  35. credsweeper/ml_model/features/morpheme_dense.py +0 -4
  36. credsweeper/ml_model/features/rule_name.py +1 -1
  37. credsweeper/ml_model/features/word_in_path.py +0 -9
  38. credsweeper/ml_model/features/word_in_postamble.py +0 -11
  39. credsweeper/ml_model/features/word_in_preamble.py +0 -11
  40. credsweeper/ml_model/features/word_in_transition.py +0 -11
  41. credsweeper/ml_model/features/word_in_value.py +0 -11
  42. credsweeper/ml_model/features/word_in_variable.py +0 -11
  43. credsweeper/ml_model/ml_validator.py +4 -3
  44. credsweeper/rules/config.yaml +238 -208
  45. credsweeper/scanner/scan_type/scan_type.py +2 -3
  46. credsweeper/scanner/scanner.py +7 -1
  47. credsweeper/secret/config.json +16 -5
  48. credsweeper/utils/pem_key_detector.py +4 -5
  49. credsweeper/utils/util.py +67 -144
  50. {credsweeper-1.11.2.dist-info → credsweeper-1.11.3.dist-info}/METADATA +1 -1
  51. {credsweeper-1.11.2.dist-info → credsweeper-1.11.3.dist-info}/RECORD +54 -53
  52. credsweeper/utils/entropy_validator.py +0 -72
  53. {credsweeper-1.11.2.dist-info → credsweeper-1.11.3.dist-info}/WHEEL +0 -0
  54. {credsweeper-1.11.2.dist-info → credsweeper-1.11.3.dist-info}/entry_points.txt +0 -0
  55. {credsweeper-1.11.2.dist-info → credsweeper-1.11.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,7 @@
1
1
  import contextlib
2
2
  import re
3
3
  import statistics
4
+ from itertools import takewhile
4
5
 
5
6
  from credsweeper.common.constants import Chars
6
7
  from credsweeper.config import Config
@@ -16,8 +17,8 @@ class ValueBase64PartCheck(Filter):
16
17
  Check that candidate is NOT a part of base64 long line
17
18
  """
18
19
 
19
- base64_pattern = re.compile(r"^(\\{1,8}[0abfnrtv]|[0-9A-Za-z+/=]){1,4000}")
20
- base64_set = set(Chars.BASE64STDPAD_CHARS.value)
20
+ base64_pattern = re.compile(r"^(\\{1,8}[0abfnrtv]|[0-9A-Za-z+/=]){1,4000}$")
21
+ base64_char_set = set(Chars.BASE64STDPAD_CHARS.value + '\\')
21
22
 
22
23
  def __init__(self, config: Config = None) -> None:
23
24
  pass
@@ -64,38 +65,46 @@ class ValueBase64PartCheck(Filter):
64
65
  elif right_end - left_start >= 2 * len_value:
65
66
  # simple analysis for data too large to yield sensible insights
66
67
  part_set = set(line[left_start:right_end])
67
- if not part_set.difference(self.base64_set):
68
+ if not part_set.difference(ValueBase64PartCheck.base64_char_set):
68
69
  # obvious case: all characters are base64 standard
69
70
  return True
70
71
 
71
- left_part = line[left_start:line_data.value_start]
72
- len_left = len(left_part)
73
- right_part = line[line_data.value_end:right_end]
74
- len_right = len(right_part)
72
+ left_part = ''.join(
73
+ takewhile(lambda x: x in ValueBase64PartCheck.base64_char_set,
74
+ reversed(line[left_start:line_data.value_start])))
75
+
76
+ right_part = ''.join(
77
+ takewhile(lambda x: x in ValueBase64PartCheck.base64_char_set, line[line_data.value_end:right_end]))
75
78
 
76
79
  min_entropy_value = ValueEntropyBase64Check.get_min_data_entropy(len_value)
77
- value_entropy = Util.get_shannon_entropy(value, Chars.BASE64STD_CHARS.value)
78
80
 
79
- if ValueEntropyBase64Check.min_length < len_left:
80
- left_entropy = Util.get_shannon_entropy(left_part, Chars.BASE64STD_CHARS.value)
81
- if len_left < len_value:
82
- left_entropy *= len_value / len_left
83
- else:
84
- left_entropy = min_entropy_value
81
+ left_entropy = Util.get_shannon_entropy(left_part)
82
+ value_entropy = Util.get_shannon_entropy(value)
83
+ right_entropy = Util.get_shannon_entropy(right_part)
84
+ common = left_part + value + right_part
85
+ common_entropy = Util.get_shannon_entropy(common)
86
+ min_entropy_common = ValueEntropyBase64Check.get_min_data_entropy(len(common))
87
+ if min_entropy_common < common_entropy:
88
+ return True
85
89
 
86
- if ValueEntropyBase64Check.min_length < len_right:
87
- right_entropy = Util.get_shannon_entropy(right_part, Chars.BASE64STD_CHARS.value)
88
- if len_right < len_value:
89
- left_entropy *= len_right / len_left
90
+ if left_entropy and right_entropy:
91
+ data = [left_entropy, value_entropy, right_entropy, min_entropy_value, common_entropy]
92
+ elif left_entropy and not right_entropy:
93
+ data = [left_entropy, value_entropy, min_entropy_value, min_entropy_value, common_entropy]
94
+ elif not left_entropy and right_entropy:
95
+ data = [value_entropy, right_entropy, min_entropy_value, min_entropy_value, common_entropy]
90
96
  else:
91
- right_entropy = min_entropy_value
97
+ return False
92
98
 
93
- data = [left_entropy, value_entropy, right_entropy, min_entropy_value]
94
99
  avg = statistics.mean(data)
95
100
  stdev = statistics.stdev(data, avg)
96
101
  avg_min = avg - 1.1 * stdev
97
- if avg_min <= left_entropy and avg_min <= right_entropy:
102
+ if (0. == left_entropy or avg_min < left_entropy or left_entropy < value_entropy < right_entropy) \
103
+ and (
104
+ 0. == right_entropy or avg_min < right_entropy or right_entropy < value_entropy < left_entropy):
98
105
  # high entropy of bound parts looks like a part of base64 long line
99
106
  return True
107
+ else:
108
+ return False
100
109
 
101
110
  return False
@@ -1,6 +1,5 @@
1
1
  import contextlib
2
2
 
3
- from credsweeper.common.constants import Chars
4
3
  from credsweeper.config import Config
5
4
  from credsweeper.credentials import LineData
6
5
  from credsweeper.file_handler.analysis_target import AnalysisTarget
@@ -32,7 +31,7 @@ class ValueDiscordBotCheck(Filter):
32
31
  id_part = line_data.value[:dot_separator_index]
33
32
  discord_id = int(Util.decode_base64(id_part, padding_safe=True, urlsafe_detect=True))
34
33
  entropy_part = line_data.value[dot_separator_index:]
35
- entropy = Util.get_shannon_entropy(entropy_part, Chars.BASE64URL_CHARS.value)
34
+ entropy = Util.get_shannon_entropy(entropy_part)
36
35
  min_entropy = ValueEntropyBase64Check.get_min_data_entropy(len(entropy_part))
37
36
  if 1000 <= discord_id and min_entropy <= entropy:
38
37
  return False
@@ -1,42 +1,22 @@
1
1
  import math
2
+ from functools import cache
2
3
 
3
- from credsweeper.common.constants import Chars
4
- from credsweeper.config import Config
5
- from credsweeper.credentials import LineData
6
- from credsweeper.file_handler.analysis_target import AnalysisTarget
7
- from credsweeper.filters import Filter
8
- from credsweeper.utils import Util
4
+ from credsweeper.filters.value_entropy_base_check import ValueEntropyBaseCheck
9
5
 
10
6
 
11
- class ValueEntropyBase32Check(Filter):
12
- """Check that candidate have Shanon Entropy (for [a-z0-9])"""
13
-
14
- def __init__(self, config: Config = None) -> None:
15
- pass
7
+ class ValueEntropyBase32Check(ValueEntropyBaseCheck):
8
+ """Base32 entropy check"""
16
9
 
17
10
  @staticmethod
11
+ @cache
18
12
  def get_min_data_entropy(x: int) -> float:
19
13
  """Returns average entropy for size of random data. Precalculated data is applied for speedup"""
20
- if 16 == x:
21
- y = 3.46
22
- elif 10 <= x:
23
- # approximation does not exceed stdev
24
- y = 0.64 * math.log2(x) + 0.9
14
+ if 8 <= x < 17:
15
+ y = 0.80569236 * math.log2(x) + 0.13439734
16
+ elif 17 <= x < 33:
17
+ y = 0.66350481 * math.log2(x) + 0.71143862
18
+ elif 33 <= x:
19
+ y = 4.04
25
20
  else:
26
21
  y = 0
27
22
  return y
28
-
29
- def run(self, line_data: LineData, target: AnalysisTarget) -> bool:
30
- """Run filter checks on received credential candidate data 'line_data'.
31
-
32
- Args:
33
- line_data: credential candidate data
34
- target: multiline target from which line data was obtained
35
-
36
- Return:
37
- True, if need to filter candidate and False if left
38
-
39
- """
40
- entropy = Util.get_shannon_entropy(line_data.value, Chars.BASE32_CHARS.value)
41
- min_entropy = ValueEntropyBase32Check.get_min_data_entropy(len(line_data.value))
42
- return min_entropy > entropy or 0 == min_entropy
@@ -1,46 +1,23 @@
1
1
  import math
2
+ from functools import cache
2
3
 
3
- from credsweeper.common.constants import Chars
4
- from credsweeper.config import Config
5
- from credsweeper.credentials import LineData
6
- from credsweeper.file_handler.analysis_target import AnalysisTarget
7
- from credsweeper.filters import Filter
8
- from credsweeper.utils import Util
4
+ from credsweeper.filters.value_entropy_base_check import ValueEntropyBaseCheck
9
5
 
10
6
 
11
- class ValueEntropyBase36Check(Filter):
12
- """Check that candidate have Shanon Entropy (for [a-z0-9])"""
13
-
14
- def __init__(self, config: Config = None) -> None:
15
- pass
7
+ class ValueEntropyBase36Check(ValueEntropyBaseCheck):
8
+ """Base36 entropy check"""
16
9
 
17
10
  @staticmethod
11
+ @cache
18
12
  def get_min_data_entropy(x: int) -> float:
19
13
  """Returns minimal entropy for size of random data. Precalculated data is applied for speedup"""
20
14
  if 15 == x:
21
- y = 3.43
22
- elif 24 == x:
23
- y = 3.91
24
- elif 25 == x:
25
- y = 3.95
26
- elif 10 <= x:
27
- # approximation does not exceed standard deviation
28
- y = 0.7 * math.log2(x) + 0.7
15
+ # workaround for Dropbox App secret
16
+ y = 3.374
17
+ elif 10 <= x < 26:
18
+ y = 0.731566857 * math.log2(x) + 0.474132
19
+ elif 26 <= x:
20
+ y = 3.9
29
21
  else:
30
22
  y = 0
31
23
  return y
32
-
33
- def run(self, line_data: LineData, target: AnalysisTarget) -> bool:
34
- """Run filter checks on received credential candidate data 'line_data'.
35
-
36
- Args:
37
- line_data: credential candidate data
38
- target: multiline target from which line data was obtained
39
-
40
- Return:
41
- True, if need to filter candidate and False if left
42
-
43
- """
44
- entropy = Util.get_shannon_entropy(line_data.value, Chars.BASE36_CHARS.value)
45
- min_entropy = ValueEntropyBase36Check.get_min_data_entropy(len(line_data.value))
46
- return min_entropy > entropy or 0 == min_entropy
@@ -1,59 +1,30 @@
1
1
  import math
2
+ from functools import cache
2
3
 
3
- from credsweeper.common.constants import Chars, ENTROPY_LIMIT_BASE64
4
- from credsweeper.config import Config
5
- from credsweeper.credentials import LineData
6
- from credsweeper.file_handler.analysis_target import AnalysisTarget
7
- from credsweeper.filters import Filter
8
- from credsweeper.utils import Util
4
+ from credsweeper.filters.value_entropy_base_check import ValueEntropyBaseCheck
9
5
 
10
6
 
11
- class ValueEntropyBase64Check(Filter):
12
- """Check that candidate have Shanon Entropy > 3 (for HEX_CHARS or BASE36_CHARS) or > 4.5 (for BASE64_CHARS)."""
13
-
14
- # If the value size is less than this value the entropy evaluation gives an imprecise result
15
- min_length = 12
16
-
17
- def __init__(self, config: Config = None) -> None:
18
- pass
7
+ class ValueEntropyBase64Check(ValueEntropyBaseCheck):
8
+ """Base64 entropy check"""
19
9
 
20
10
  @staticmethod
11
+ @cache
21
12
  def get_min_data_entropy(x: int) -> float:
22
13
  """Returns minimal average entropy for size of random data. Precalculated round data is applied for speedup"""
23
- if 18 == x:
24
- y = 3.8
25
- elif 20 == x:
26
- y = 3.9
27
- elif 24 == x:
28
- y = 4.1
29
- elif 32 == x:
30
- y = 4.4
31
- elif ValueEntropyBase64Check.min_length <= x < 35:
32
- # logarithm base 2 - slow, but precise. Approximation does not exceed stdev
33
- y = 0.77 * math.log2(x) + 0.62
34
- elif 35 <= x < 60:
35
- y = ENTROPY_LIMIT_BASE64
36
- elif 60 <= x:
37
- # the entropy grows slowly after 60
38
- y = 5.0
14
+ if 12 <= x < 18:
15
+ y = 0.915 * math.log2(x) - 0.047
16
+ elif 18 <= x < 35:
17
+ y = 0.767 * math.log2(x) + 0.5677
18
+ elif 35 <= x < 65:
19
+ y = 0.944 * math.log2(x) - 0.009 * x - 0.04
20
+ elif 65 <= x < 256:
21
+ y = 0.621 * math.log2(x) - 0.003 * x + 1.54
22
+ elif 256 <= x < 512:
23
+ y = 5.77
24
+ elif 512 <= x < 1024:
25
+ y = 5.89
26
+ elif 1024 <= x:
27
+ y = 5.94
39
28
  else:
40
29
  y = 0
41
30
  return y
42
-
43
- def run(self, line_data: LineData, target: AnalysisTarget) -> bool:
44
- """Run filter checks on received credential candidate data 'line_data'.
45
-
46
- Args:
47
- line_data: credential candidate data
48
- target: multiline target from which line data was obtained
49
-
50
- Return:
51
- True, if need to filter candidate and False if left
52
-
53
- """
54
- if '-' in line_data.value or '_' in line_data.value:
55
- entropy = Util.get_shannon_entropy(line_data.value, Chars.BASE64URL_CHARS.value)
56
- else:
57
- entropy = Util.get_shannon_entropy(line_data.value, Chars.BASE64STD_CHARS.value)
58
- min_entropy = ValueEntropyBase64Check.get_min_data_entropy(len(line_data.value))
59
- return min_entropy > entropy or 0 == min_entropy
@@ -0,0 +1,37 @@
1
+ from abc import abstractmethod
2
+
3
+ from credsweeper.config import Config
4
+ from credsweeper.credentials import LineData
5
+ from credsweeper.file_handler.analysis_target import AnalysisTarget
6
+ from credsweeper.filters import Filter
7
+ from credsweeper.utils import Util
8
+
9
+
10
+ class ValueEntropyBaseCheck(Filter):
11
+ """Check that candidate value has minimal Shanon Entropy for appropriated base"""
12
+
13
+ def __init__(self, config: Config = None) -> None:
14
+ pass
15
+
16
+ @staticmethod
17
+ @abstractmethod
18
+ def get_min_data_entropy(x: int) -> float:
19
+ """Returns minimal entropy for size of data"""
20
+ raise NotImplementedError()
21
+
22
+ def run(self, line_data: LineData, target: AnalysisTarget) -> bool:
23
+ """Run filter checks on received credential candidate data 'line_data'.
24
+
25
+ Args:
26
+ line_data: credential candidate data
27
+ target: multiline target from which line data was obtained
28
+
29
+ Return:
30
+ True, when need to filter candidate and False if left
31
+
32
+ """
33
+ entropy = Util.get_shannon_entropy(line_data.value)
34
+ min_entropy = self.get_min_data_entropy(len(line_data.value))
35
+ if min_entropy > entropy or 0 == min_entropy:
36
+ return True
37
+ return False
@@ -53,7 +53,7 @@ class ValueFilePathCheck(Filter):
53
53
  break
54
54
  else:
55
55
  # all symbols are from base64 alphabet
56
- entropy = Util.get_shannon_entropy(value, Chars.BASE64STDPAD_CHARS.value)
56
+ entropy = Util.get_shannon_entropy(value)
57
57
  if 0 == min_entropy or min_entropy > entropy:
58
58
  contains_unix_separator = 1 < value.count('/')
59
59
  else:
@@ -7,9 +7,9 @@ from credsweeper.filters import Filter
7
7
 
8
8
 
9
9
  class ValueHexNumberCheck(Filter):
10
- """Check value if it a value in 32 or 64 bits hex representation"""
10
+ """Check value if it is a value up to 64 bits hex representation"""
11
11
 
12
- HEX_32_64_VALUE_REGEX = re.compile(r"^0x([0-9a-f]{8}){1,2}$")
12
+ HEX_08_64_VALUE_REGEX = re.compile(r"^0x[0-9a-f]{1,16}$")
13
13
 
14
14
  def __init__(self, config: Config = None) -> None:
15
15
  pass
@@ -26,6 +26,6 @@ class ValueHexNumberCheck(Filter):
26
26
 
27
27
  """
28
28
  value = line_data.value.lower()
29
- if len(value) in [10, 18] and ValueHexNumberCheck.HEX_32_64_VALUE_REGEX.match(value):
29
+ if ValueHexNumberCheck.HEX_08_64_VALUE_REGEX.match(value):
30
30
  return True
31
31
  return False
@@ -15,14 +15,13 @@ class ValueJsonWebTokenCheck(Filter):
15
15
  https://www.iana.org/assignments/jose/jose.xhtml
16
16
  """
17
17
  header_keys = {
18
- "alg", "jku", "jwk", "kid", "x5u", "x5c", "x5t", "x5t#S256", "typ", "cty", "crit", "alg", "enc", "zip", "jku",
19
- "jwk", "kid", "x5u", "x5c", "x5t", "x5t#S256", "typ", "cty", "crit", "epk", "apu", "apv", "iv", "tag", "p2s",
20
- "p2c", "iss", "sub", "aud", "b64", "ppt", "url", "nonce", "svt"
18
+ "kid", "x5u", "x5t", "x5t#S256", "typ", "cty", "crit", "alg", "enc", "zip", "jku", "jwk", "x5c", "epk", "apu",
19
+ "apv", "iv", "tag", "p2s", "p2c", "iss", "sub", "aud", "b64", "ppt", "url", "nonce", "svt"
21
20
  }
22
21
  payload_keys = {
23
22
  "iss", "sub", "aud", "exp", "nbf", "iat", "jti", "kty", "use", "key_ops", "alg", "enc", "zip", "jku", "jwk",
24
- "kid", "x5u", "x5c", "x5t", "x5t#S256", "crv", "x", "y", "d", "n", "e", "d", "p", "q", "dp", "dq", "qi", "oth",
25
- "k", "crv", "d", "x", "ext", "crit", "keys", "id", "role", "token", "secret", "password", "nonce"
23
+ "kid", "x5u", "x5c", "x5t", "x5t#S256", "x", "y", "d", "n", "e", "p", "q", "dp", "dq", "qi", "oth", "k", "crv",
24
+ "ext", "crit", "keys", "id", "role", "token", "secret", "password", "nonce"
26
25
  }
27
26
 
28
27
  def __init__(self, config: Config = None) -> None:
@@ -1,3 +1,5 @@
1
+ import re
2
+
1
3
  from credsweeper.config import Config
2
4
  from credsweeper.credentials import LineData
3
5
  from credsweeper.file_handler.analysis_target import AnalysisTarget
@@ -9,6 +11,7 @@ class ValueStringTypeCheck(Filter):
9
11
 
10
12
  If it is, then checks if line_data really have string literal declaration.
11
13
  Comment rows in source files (start with //, /\*, etc) ignored.
14
+ Multiple bytes scenario allowed [123,23,54,67,78,89] or {0xae, 0x54, 0x55, 0xff}
12
15
 
13
16
  True if:
14
17
 
@@ -20,6 +23,8 @@ class ValueStringTypeCheck(Filter):
20
23
  False otherwise
21
24
  """
22
25
 
26
+ MULTIBYTE_PATTERN = re.compile(r"(\s*(0x)?[0-9a-f]{1,3}\s*,){8,80}", flags=re.IGNORECASE)
27
+
23
28
  def __init__(self, config: Config) -> None:
24
29
  self.check_for_literals = config.check_for_literals
25
30
 
@@ -37,10 +42,13 @@ class ValueStringTypeCheck(Filter):
37
42
  if not self.check_for_literals or line_data.url_part:
38
43
  return False
39
44
 
40
- not_quoted = not line_data.is_well_quoted_value
41
- not_comment = not line_data.is_comment()
45
+ if ValueStringTypeCheck.MULTIBYTE_PATTERN.match(line_data.value):
46
+ return False
42
47
 
43
- if line_data.is_source_file_with_quotes() and not_comment and not_quoted and not line_data.is_quoted \
48
+ if line_data.is_source_file_with_quotes() \
49
+ and not line_data.is_comment() \
50
+ and not line_data.is_well_quoted_value \
51
+ and not line_data.is_quoted \
44
52
  and line_data.separator and '=' in line_data.separator:
45
53
  # heterogeneous code e.g. YAML in Python uses colon sign instead equals
46
54
  return True
@@ -1,6 +1,5 @@
1
1
  from typing import Tuple
2
2
 
3
- from credsweeper.config import Config
4
3
  from credsweeper.filters.value_token_base_check import ValueTokenBaseCheck
5
4
 
6
5
 
@@ -21,9 +20,6 @@ class ValueTokenBase32Check(ValueTokenBaseCheck):
21
20
  64: ((3.4805990476190476, 0.28572156450556774), (2.035756800745673, 0.18815721535870078)),
22
21
  }
23
22
 
24
- def __init__(self, config: Config = None) -> None:
25
- super().__init__(config)
26
-
27
23
  @staticmethod
28
24
  def get_stat_range(size: int) -> Tuple[Tuple[float, float], Tuple[float, float]]:
29
25
  """Returns minimal, maximal for hop and deviation. Precalculated data is applied for speedup"""
@@ -1,6 +1,5 @@
1
1
  from typing import Tuple
2
2
 
3
- from credsweeper.config import Config
4
3
  from credsweeper.filters.value_token_base_check import ValueTokenBaseCheck
5
4
 
6
5
 
@@ -21,9 +20,6 @@ class ValueTokenBase36Check(ValueTokenBaseCheck):
21
20
  64: ((3.7190009761904763, 0.30325954360127116), (2.1751172797904093, 0.1942582237461476)),
22
21
  }
23
22
 
24
- def __init__(self, config: Config = None) -> None:
25
- super().__init__(config)
26
-
27
23
  @staticmethod
28
24
  def get_stat_range(size: int) -> Tuple[Tuple[float, float], Tuple[float, float]]:
29
25
  """Returns minimal, maximal for hop and deviation. Precalculated data is applied for speedup"""
@@ -1,6 +1,5 @@
1
1
  from typing import Tuple
2
2
 
3
- from credsweeper.config import Config
4
3
  from credsweeper.filters.value_token_base_check import ValueTokenBaseCheck
5
4
 
6
5
 
@@ -21,9 +20,6 @@ class ValueTokenBase64Check(ValueTokenBaseCheck):
21
20
  64: ((3.7625271746031745, 0.31733579704946846), (2.257532519514275, 0.20571908142867643)),
22
21
  }
23
22
 
24
- def __init__(self, config: Config = None) -> None:
25
- super().__init__(config)
26
-
27
23
  @staticmethod
28
24
  def get_stat_range(size: int) -> Tuple[Tuple[float, float], Tuple[float, float]]:
29
25
  """Returns minimal, maximal for hop and deviation. Precalculated data is applied for speedup"""
@@ -17,7 +17,7 @@ class ValueTokenCheck(Filter):
17
17
 
18
18
  """
19
19
 
20
- SPLIT_PATTERN = r" |;|\)|\(|{|}|<|>|\[|\]|`"
20
+ SPLIT_PATTERN = r"(?<!,) (?!,)|;|\)|\(|{|}|<|>|\[|\]|`"
21
21
 
22
22
  def __init__(self, config: Config = None) -> None:
23
23
  pass
@@ -15,7 +15,7 @@ class FileExtension(WordIn):
15
15
  """
16
16
 
17
17
  def __init__(self, extensions: List[str]) -> None:
18
- super().__init__(extensions)
18
+ super().__init__(words=extensions)
19
19
 
20
20
  def __call__(self, candidates: List[Candidate]) -> np.ndarray:
21
21
  extension_set = set([candidate.line_data_list[0].file_type.lower() for candidate in candidates])
@@ -6,10 +6,6 @@ from credsweeper.ml_model.features.feature import Feature
6
6
  class MorphemeDense(Feature):
7
7
  """Feature calculates morphemes density for a value"""
8
8
 
9
- def __init__(self) -> None:
10
- """Class initializer"""
11
- super().__init__()
12
-
13
9
  def extract(self, candidate: Candidate) -> float:
14
10
  if value := candidate.line_data_list[0].value.lower():
15
11
  morphemes_counter = 0
@@ -15,7 +15,7 @@ class RuleName(WordIn):
15
15
  """
16
16
 
17
17
  def __init__(self, rule_names: List[str]) -> None:
18
- super().__init__(rule_names)
18
+ super().__init__(words=rule_names)
19
19
 
20
20
  def __call__(self, candidates: List[Candidate]) -> np.ndarray:
21
21
  candidate_rule_set = set(x.rule_name for x in candidates)
@@ -10,15 +10,6 @@ from credsweeper.ml_model.features.word_in import WordIn
10
10
  class WordInPath(WordIn):
11
11
  """Categorical feature that corresponds to words in path (POSIX, lowercase)"""
12
12
 
13
- def __init__(self, words: List[str]) -> None:
14
- """WordInPath constructor
15
-
16
- Args:
17
- words: list of predefined words - MUST BE IN LOWER CASE & POSIX
18
-
19
- """
20
- super().__init__(words)
21
-
22
13
  def __call__(self, candidates: List[Candidate]) -> np.ndarray:
23
14
  # actually there must be one path because the candidates are grouped before
24
15
  if file_path := candidates[0].line_data_list[0].path:
@@ -1,5 +1,3 @@
1
- from typing import List
2
-
3
1
  import numpy as np
4
2
 
5
3
  from credsweeper.common.constants import ML_HUNK
@@ -10,15 +8,6 @@ from credsweeper.ml_model.features.word_in import WordIn
10
8
  class WordInPostamble(WordIn):
11
9
  """Feature is true if line contains at least one word from predefined list."""
12
10
 
13
- def __init__(self, words: List[str]) -> None:
14
- """Feature returns array of matching words
15
-
16
- Args:
17
- words: list of predefined words - MUST BE IN LOWER CASE
18
-
19
- """
20
- super().__init__(words)
21
-
22
11
  def extract(self, candidate: Candidate) -> np.ndarray:
23
12
  """Returns true if any words in a part of line after value"""
24
13
  postamble_end = len(candidate.line_data_list[0].line) \
@@ -1,5 +1,3 @@
1
- from typing import List
2
-
3
1
  import numpy as np
4
2
 
5
3
  from credsweeper.common.constants import ML_HUNK
@@ -10,15 +8,6 @@ from credsweeper.ml_model.features.word_in import WordIn
10
8
  class WordInPreamble(WordIn):
11
9
  """Feature is true if line contains at least one word from predefined list."""
12
10
 
13
- def __init__(self, words: List[str]) -> None:
14
- """Feature returns array of matching words
15
-
16
- Args:
17
- words: list of predefined words - MUST BE IN LOWER CASE
18
-
19
- """
20
- super().__init__(words)
21
-
22
11
  def extract(self, candidate: Candidate) -> np.ndarray:
23
12
  """Returns true if any words in line before variable or value"""
24
13
  if 0 <= candidate.line_data_list[0].variable_start:
@@ -1,5 +1,3 @@
1
- from typing import List
2
-
3
1
  import numpy as np
4
2
 
5
3
  from credsweeper.credentials import Candidate
@@ -9,15 +7,6 @@ from credsweeper.ml_model.features.word_in import WordIn
9
7
  class WordInTransition(WordIn):
10
8
  """Feature is true if line contains at least one word from predefined list."""
11
9
 
12
- def __init__(self, words: List[str]) -> None:
13
- """Feature returns array of matching words
14
-
15
- Args:
16
- words: list of predefined words - MUST BE IN LOWER CASE
17
-
18
- """
19
- super().__init__(words)
20
-
21
10
  def extract(self, candidate: Candidate) -> np.ndarray:
22
11
  """Returns true if any words between variable and value"""
23
12
  if 0 <= candidate.line_data_list[0].variable_end < candidate.line_data_list[0].value_start:
@@ -1,5 +1,3 @@
1
- from typing import List
2
-
3
1
  import numpy as np
4
2
 
5
3
  from credsweeper.credentials import Candidate
@@ -9,15 +7,6 @@ from credsweeper.ml_model.features.word_in import WordIn
9
7
  class WordInValue(WordIn):
10
8
  """Feature returns true if candidate value contains at least one word from predefined list."""
11
9
 
12
- def __init__(self, words: List[str]) -> None:
13
- """Feature is true if candidate value contains at least one predefined word.
14
-
15
- Args:
16
- words: list of predefined words - MUST BE IN LOWER CASE and SORTED (preferred)
17
-
18
- """
19
- super().__init__(words)
20
-
21
10
  def extract(self, candidate: Candidate) -> np.ndarray:
22
11
  """Returns array of matching words for first line"""
23
12
  if value := candidate.line_data_list[0].value:
@@ -1,5 +1,3 @@
1
- from typing import List
2
-
3
1
  import numpy as np
4
2
 
5
3
  from credsweeper.credentials import Candidate
@@ -9,15 +7,6 @@ from credsweeper.ml_model.features.word_in import WordIn
9
7
  class WordInVariable(WordIn):
10
8
  """Feature returns array of words matching in variable"""
11
9
 
12
- def __init__(self, words: List[str]) -> None:
13
- """Feature is true if candidate value contains at least one predefined word.
14
-
15
- Args:
16
- words: list of predefined words - MUST BE IN LOWER CASE
17
-
18
- """
19
- super().__init__(words)
20
-
21
10
  def extract(self, candidate: Candidate) -> np.ndarray:
22
11
  """Returns array of matching words for first line"""
23
12
  if variable := candidate.line_data_list[0].variable: