credsweeper 1.11.3__py3-none-any.whl → 1.11.4__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 (35) hide show
  1. credsweeper/__init__.py +1 -1
  2. credsweeper/__main__.py +1 -1
  3. credsweeper/app.py +21 -44
  4. credsweeper/common/constants.py +2 -5
  5. credsweeper/credentials/candidate_key.py +1 -1
  6. credsweeper/credentials/credential_manager.py +4 -3
  7. credsweeper/credentials/line_data.py +2 -5
  8. credsweeper/deep_scanner/deb_scanner.py +48 -0
  9. credsweeper/deep_scanner/deep_scanner.py +47 -36
  10. credsweeper/deep_scanner/gzip_scanner.py +1 -1
  11. credsweeper/file_handler/byte_content_provider.py +2 -2
  12. credsweeper/file_handler/content_provider.py +1 -1
  13. credsweeper/file_handler/data_content_provider.py +2 -2
  14. credsweeper/file_handler/diff_content_provider.py +2 -2
  15. credsweeper/file_handler/file_path_extractor.py +1 -1
  16. credsweeper/file_handler/files_provider.py +2 -4
  17. credsweeper/file_handler/patches_provider.py +1 -1
  18. credsweeper/file_handler/string_content_provider.py +2 -2
  19. credsweeper/file_handler/struct_content_provider.py +1 -1
  20. credsweeper/file_handler/text_content_provider.py +2 -2
  21. credsweeper/filters/value_base64_encoded_pem_check.py +1 -1
  22. credsweeper/filters/value_entropy_base64_check.py +2 -6
  23. credsweeper/filters/value_pattern_check.py +64 -16
  24. credsweeper/ml_model/features/file_extension.py +1 -1
  25. credsweeper/ml_model/ml_validator.py +43 -21
  26. credsweeper/rules/config.yaml +3 -3
  27. credsweeper/rules/rule.py +3 -3
  28. credsweeper/utils/hop_stat.py +3 -3
  29. credsweeper/utils/pem_key_detector.py +5 -3
  30. credsweeper/utils/util.py +13 -6
  31. {credsweeper-1.11.3.dist-info → credsweeper-1.11.4.dist-info}/METADATA +1 -1
  32. {credsweeper-1.11.3.dist-info → credsweeper-1.11.4.dist-info}/RECORD +35 -34
  33. {credsweeper-1.11.3.dist-info → credsweeper-1.11.4.dist-info}/WHEEL +0 -0
  34. {credsweeper-1.11.3.dist-info → credsweeper-1.11.4.dist-info}/entry_points.txt +0 -0
  35. {credsweeper-1.11.3.dist-info → credsweeper-1.11.4.dist-info}/licenses/LICENSE +0 -0
@@ -33,33 +33,33 @@ class ValuePatternCheck(Filter):
33
33
  # use non whitespace symbol pattern
34
34
  self.pattern = re.compile(fr"(\S)\1{{{str(self.pattern_len - 1)},}}")
35
35
 
36
- def equal_pattern_check(self, line_data_value: str) -> bool:
36
+ def equal_pattern_check(self, value: str) -> bool:
37
37
  """Check if candidate value contain 4 and more same chars or numbers sequences.
38
38
 
39
39
  Args:
40
- line_data_value: string variable, credential candidate value
40
+ value: string variable, credential candidate value
41
41
 
42
42
  Return:
43
43
  True if contain and False if not
44
44
 
45
45
  """
46
- if self.pattern.findall(line_data_value):
46
+ if self.pattern.findall(value):
47
47
  return True
48
48
  return False
49
49
 
50
- def ascending_pattern_check(self, line_data_value: str) -> bool:
50
+ def ascending_pattern_check(self, value: str) -> bool:
51
51
  """Check if candidate value contain 4 and more ascending chars or numbers sequences.
52
52
 
53
53
  Arg:
54
- line_data_value: credential candidate value
54
+ value: credential candidate value
55
55
 
56
56
  Return:
57
57
  True if contain and False if not
58
58
 
59
59
  """
60
60
  count = 1
61
- for key in range(len(line_data_value) - 1):
62
- if ord(line_data_value[key + 1]) - ord(line_data_value[key]) == 1:
61
+ for key in range(len(value) - 1):
62
+ if ord(value[key + 1]) - ord(value[key]) == 1:
63
63
  count += 1
64
64
  else:
65
65
  count = 1
@@ -68,19 +68,19 @@ class ValuePatternCheck(Filter):
68
68
  return True
69
69
  return False
70
70
 
71
- def descending_pattern_check(self, line_data_value: str) -> bool:
71
+ def descending_pattern_check(self, value: str) -> bool:
72
72
  """Check if candidate value contain 4 and more descending chars or numbers sequences.
73
73
 
74
74
  Arg:
75
- line_data_value: string variable, credential candidate value
75
+ value: string variable, credential candidate value
76
76
 
77
77
  Return:
78
78
  boolean variable. True if contain and False if not
79
79
 
80
80
  """
81
81
  count = 1
82
- for key in range(len(line_data_value) - 1):
83
- if ord(line_data_value[key]) - ord(line_data_value[key + 1]) == 1:
82
+ for key in range(len(value) - 1):
83
+ if ord(value[key]) - ord(value[key + 1]) == 1:
84
84
  count += 1
85
85
  else:
86
86
  count = 1
@@ -89,6 +89,57 @@ class ValuePatternCheck(Filter):
89
89
  return True
90
90
  return False
91
91
 
92
+ def check_val(self, value: str) -> bool:
93
+ """Cumulative value check.
94
+
95
+ Arg:
96
+ value: string variable, credential candidate value
97
+
98
+ Return:
99
+ boolean variable. True if contain and False if not
100
+
101
+ """
102
+ if self.equal_pattern_check(value):
103
+ return True
104
+ if self.ascending_pattern_check(value):
105
+ return True
106
+ if self.descending_pattern_check(value):
107
+ return True
108
+ return False
109
+
110
+ def duple_pattern_check(self, value: str) -> bool:
111
+ """Check if candidate value is a duplet value with possible patterns.
112
+
113
+ Arg:
114
+ value: string variable, credential candidate value
115
+
116
+ Return:
117
+ boolean variable. True if contain and False if not
118
+
119
+ """
120
+ # 001122334455... case
121
+ pair_duple = True
122
+ # 0102030405... case
123
+ even_duple = True
124
+ even_prev = value[0]
125
+ even_value = value[0::2]
126
+ # 1020304050... case
127
+ odd_duple = True
128
+ odd_prev = value[1]
129
+ odd_value = value[1::2]
130
+ for even_i, odd_i in zip(even_value, odd_value):
131
+ pair_duple &= even_i == odd_i
132
+ even_duple &= even_i == even_prev
133
+ odd_duple &= odd_i == odd_prev
134
+ if not pair_duple and not even_duple and not odd_duple:
135
+ break
136
+ else:
137
+ if pair_duple or odd_duple:
138
+ return self.check_val(even_value)
139
+ if even_duple:
140
+ return self.check_val(odd_value)
141
+ return False
142
+
92
143
  def run(self, line_data: LineData, target: AnalysisTarget) -> bool:
93
144
  """Run filter checks on received credential candidate data 'line_data'.
94
145
 
@@ -103,13 +154,10 @@ class ValuePatternCheck(Filter):
103
154
  if len(line_data.value) < self.pattern_len:
104
155
  return True
105
156
 
106
- if self.equal_pattern_check(line_data.value):
107
- return True
108
-
109
- if self.ascending_pattern_check(line_data.value):
157
+ if self.check_val(line_data.value):
110
158
  return True
111
159
 
112
- if self.descending_pattern_check(line_data.value):
160
+ if 2 * self.pattern_len <= len(line_data.value) and self.duple_pattern_check(line_data.value):
113
161
  return True
114
162
 
115
163
  return False
@@ -18,7 +18,7 @@ class FileExtension(WordIn):
18
18
  super().__init__(words=extensions)
19
19
 
20
20
  def __call__(self, candidates: List[Candidate]) -> np.ndarray:
21
- extension_set = set([candidate.line_data_list[0].file_type.lower() for candidate in candidates])
21
+ extension_set = set(candidate.line_data_list[0].file_type.lower() for candidate in candidates)
22
22
  return self.word_in_set(extension_set)
23
23
 
24
24
  def extract(self, candidate: Candidate) -> Any:
@@ -1,10 +1,11 @@
1
1
  import hashlib
2
+ import json
2
3
  import logging
3
4
  from pathlib import Path
4
5
  from typing import List, Tuple, Union, Optional, Dict
5
6
 
6
7
  import numpy as np
7
- import onnxruntime as ort
8
+ from onnxruntime import InferenceSession
8
9
 
9
10
  import credsweeper.ml_model.features as features
10
11
  from credsweeper.common.constants import ThresholdPreset, ML_HUNK
@@ -22,6 +23,8 @@ class MlValidator:
22
23
  # applied for unknown characters
23
24
  FAKE_CHAR = '\x01'
24
25
 
26
+ _dir_path = Path(__file__).parent
27
+
25
28
  def __init__(
26
29
  self, #
27
30
  threshold: Union[float, ThresholdPreset], #
@@ -36,35 +39,36 @@ class MlValidator:
36
39
  ml_model: path to ml model
37
40
  ml_providers: coma separated list of providers https://onnxruntime.ai/docs/execution-providers/
38
41
  """
39
- dir_path = Path(__file__).parent
42
+ self.__session: Optional[InferenceSession] = None
40
43
 
41
44
  if ml_config:
42
45
  ml_config_path = Path(ml_config)
43
46
  else:
44
- ml_config_path = dir_path / "ml_config.json"
47
+ ml_config_path = MlValidator._dir_path / "ml_config.json"
45
48
  with open(ml_config_path, "rb") as f:
46
- md5_config = hashlib.md5(f.read()).hexdigest()
49
+ __ml_config_data = f.read()
50
+
51
+ model_config = json.loads(__ml_config_data)
47
52
 
48
53
  if ml_model:
49
54
  ml_model_path = Path(ml_model)
50
55
  else:
51
- ml_model_path = dir_path / "ml_model.onnx"
56
+ ml_model_path = MlValidator._dir_path / "ml_model.onnx"
52
57
  with open(ml_model_path, "rb") as f:
53
- md5_model = hashlib.md5(f.read()).hexdigest()
58
+ self.__ml_model_data = f.read()
54
59
 
55
60
  if ml_providers:
56
- providers = ml_providers.split(',')
61
+ self.providers = ml_providers.split(',')
57
62
  else:
58
- providers = ["CPUExecutionProvider"]
59
- self.model_session = ort.InferenceSession(ml_model_path, providers=providers)
63
+ self.providers = ["CPUExecutionProvider"]
60
64
 
61
- model_config = Util.json_load(ml_config_path)
62
65
  if isinstance(threshold, float):
63
66
  self.threshold = threshold
64
67
  elif isinstance(threshold, ThresholdPreset) and "thresholds" in model_config:
65
68
  self.threshold = model_config["thresholds"][threshold.value]
66
69
  else:
67
70
  self.threshold = 0.5
71
+ logger.warning(f"Use fallback threshold value: {self.threshold}")
68
72
 
69
73
  char_set = set(model_config["char_set"])
70
74
  if len(char_set) != len(model_config["char_set"]):
@@ -80,26 +84,44 @@ class MlValidator:
80
84
 
81
85
  self.common_feature_list = []
82
86
  self.unique_feature_list = []
83
- logger.info("Init ML validator with %s provider; config:'%s' md5:%s model:'%s' md5:%s", providers,
84
- ml_config_path, md5_config, ml_model_path, md5_model)
85
- logger.debug("ML validator details: %s", model_config)
87
+ if logger.isEnabledFor(logging.INFO):
88
+ config_dbg = str(model_config) if logger.isEnabledFor(logging.DEBUG) else ''
89
+ config_md5 = hashlib.md5(__ml_config_data).hexdigest()
90
+ model_md5 = hashlib.md5(self.__ml_model_data).hexdigest()
91
+ logger.info("Init ML validator with providers: '%s' ; model:'%s' md5:%s ; config:'%s' md5:%s ; %s",
92
+ self.providers, ml_config_path, config_md5, ml_model_path, model_md5, config_dbg)
86
93
  for feature_definition in model_config["features"]:
87
94
  feature_class = feature_definition["type"]
88
95
  kwargs = feature_definition.get("kwargs", {})
89
96
  feature_constructor = getattr(features, feature_class, None)
90
97
  if feature_constructor is None:
91
- raise ValueError(f'Error while parsing model details. Cannot create feature "{feature_class}"')
98
+ raise ValueError(f"Error while parsing model details. Cannot create feature '{feature_class}'"
99
+ f" from {feature_definition}")
92
100
  try:
93
101
  feature = feature_constructor(**kwargs)
94
102
  except TypeError:
95
- logger.error(f'Error while parsing model details. Cannot create feature "{feature_class}"'
96
- f' with kwargs "{kwargs}"')
103
+ logger.error(f"Error while parsing model details. Cannot create feature '{feature_class}'"
104
+ f" from {feature_definition}")
97
105
  raise
98
106
  if feature_definition["type"] in ["RuleName"]:
99
107
  self.unique_feature_list.append(feature)
100
108
  else:
101
109
  self.common_feature_list.append(feature)
102
110
 
111
+ def __reduce__(self):
112
+ # TypeError: cannot pickle 'onnxruntime.capi.onnxruntime_pybind11_state.InferenceSession' object
113
+ self.__session = None
114
+ return super().__reduce__()
115
+
116
+ @property
117
+ def session(self) -> InferenceSession:
118
+ """session getter to prevent pickle error"""
119
+ if not self.__session:
120
+ self.__session = InferenceSession(self.__ml_model_data, providers=self.providers)
121
+ if not self.__session:
122
+ raise RuntimeError("InferenceSession was not initialized!")
123
+ return self.__session
124
+
103
125
  def encode(self, text: str, limit: int) -> np.ndarray:
104
126
  """Encodes prepared text to array"""
105
127
  result_array: np.ndarray = np.zeros(shape=(limit, self.num_classes), dtype=np.float32)
@@ -136,7 +158,7 @@ class MlValidator:
136
158
  "value_input": value_input.astype(np.float32),
137
159
  "feature_input": feature_input.astype(np.float32),
138
160
  }
139
- result = self.model_session.run(output_names=None, input_feed=input_feed)
161
+ result = self.session.run(output_names=None, input_feed=input_feed)
140
162
  if result and isinstance(result[0], np.ndarray):
141
163
  return result[0]
142
164
  raise RuntimeError(f"Unexpected type {type(result[0])}")
@@ -178,8 +200,8 @@ class MlValidator:
178
200
  default_candidate = candidates[0]
179
201
  line_input = self.encode_line(default_candidate.line_data_list[0].line,
180
202
  default_candidate.line_data_list[0].value_start)[np.newaxis]
181
- variable = ""
182
- value = ""
203
+ variable = ''
204
+ value = ''
183
205
  for candidate in candidates:
184
206
  if not variable and candidate.line_data_list[0].variable:
185
207
  variable = candidate.line_data_list[0].variable
@@ -251,8 +273,8 @@ class MlValidator:
251
273
  features_list)
252
274
  is_cred = probability > self.threshold
253
275
  if logger.isEnabledFor(logging.DEBUG):
254
- for i in range(len(is_cred)):
255
- logger.debug("ML decision: %s with prediction: %s for value: %s", is_cred[i], probability[i],
276
+ for i, decision in enumerate(is_cred):
277
+ logger.debug("ML decision: %s with prediction: %s for value: %s", decision, probability[i],
256
278
  group_list[i][0])
257
279
  # apply cast to float to avoid json export issue
258
280
  return is_cred, probability.astype(float)
@@ -3,7 +3,7 @@
3
3
  confidence: weak
4
4
  type: pattern
5
5
  values:
6
- - (?P<variable>(\w*(?i:비밀번호|비번|패스워드|키|암호화?|토큰|(?<!by)pass(?!ed|ing|es|age)|\bpwd?\b|token|secret|key|cred)\w*)\s*(설정은|[=:!]{1,3}))?\s*([._0-9A-Za-z\[\]]*get(env)?\s*\(\s*(?(variable)[^,]+)|[\"'\\]*(\\*(['\"]|&(quot|apos);)){0,4}(\w*(?i:(?<!by)pass(?!ed|ing|es|age|\s+[a-z]{3,80})|\bpwd?\b|token|secret|key|cred)\w*)(\\*(['\"]|&(quot|apos);)){0,4})\s*,\s*(default\s*=\s*)?([brufl@]{1,2}(?=\\*['\"&]))?(?P<lq>(\\*(['\"]|&(quot|apos);)){1,4})(?P<value>(.(?!(?P=lq))){4,80}.?)
6
+ - (?P<variable>(\w*(?i:비밀번호|비번|패스워드|키|암호화?|토큰|(?<!by)pass(?!ed|ing|ion|es|age)|\bpwd?\b|token|secret|key|cred)\w*)\s*(설정은|[=:!]{1,3}))?\s*([._0-9A-Za-z\[\]]*get(env)?\s*\(\s*(?(variable)[^,]+)|[\"'\\]*(\\*(['\"]|&(quot|apos);)){0,4}(\w*(?i:(?<!by)pass(?!ed|ing|ion|es|age|\s+[a-z]{3,80})|\bpwd?\b|token|secret|key|cred)\w*)(\\*(['\"]|&(quot|apos);)){0,4})\s*,\s*(default\s*=\s*)?([brufl@]{1,2}(?=\\*['\"&]))?(?P<lq>(\\*(['\"]|&(quot|apos);)){1,4})(?P<value>(.(?!(?P=lq))){4,80}.?)
7
7
  filter_type:
8
8
  - ValueAllowlistCheck
9
9
  - LineGitBinaryCheck
@@ -34,7 +34,7 @@
34
34
  confidence: weak
35
35
  type: pattern
36
36
  values:
37
- - (?P<wrap>[`'\"(])?\s*(?P<variable>(\w*(?i:(?<!by)passw?o?r?d?s?(?!ed|ing|es|age)|pwd?\b|\bp/w\b|token|secret|key|credential)\w*|비밀번호|비번|패스워드|키|암호화?|토큰))[`'\"]*(\s+(?i:is|are|was|were)(\s*[:-])?\s+|\s*(설정은|[=:!]{1,3})\s*)(?P<quote>[`'\"]{1,6})?(?P<value>(?(quote)(?(wrap)[^`'\")]{4,80}|[^`'\"]{4,80})|(?(wrap)[^`'\")]{4,80}|\S{4,80})))
37
+ - (?P<wrap>[`'\"(])?\s*(?P<variable>(\w*(?i:(?<!by)passw?o?r?d?s?(?!ed|ing|ion|es|age)|pwd?\b|\bp/w\b|token|secret|key|credential)\w*|비밀번호|비번|패스워드|키|암호화?|토큰))[`'\"]*(\s+(?i:is|are|was|were)(\s*[:-])?\s+|\s*(설정은|[=:!]{1,3})\s*)(?P<quote>[`'\"]{1,6})?(?P<value>(?(quote)(?(wrap)[^`'\")]{4,80}|[^`'\"]{4,80})|(?(wrap)[^`'\")]{4,80}|\S{4,80})))
38
38
  filter_type:
39
39
  - ValueAllowlistCheck
40
40
  - LineGitBinaryCheck
@@ -1481,7 +1481,7 @@
1481
1481
  confidence: moderate
1482
1482
  type: keyword
1483
1483
  values:
1484
- - (?<!by)pass(?!ed|ing|es|age|\s+[a-z]{3,80})|pw(d|\b)
1484
+ - (?<!by)pass(?!ed|ing|ion|es|age|\s+[a-z]{3,80})|pw(d|\b)
1485
1485
  filter_type: PasswordKeyword
1486
1486
  use_ml: true
1487
1487
  min_line_len: 10
credsweeper/rules/rule.py CHANGED
@@ -179,7 +179,6 @@ class Rule:
179
179
  for value in _values:
180
180
  _pattern = KeywordPattern.get_keyword_pattern(value)
181
181
  _patterns.append(_pattern)
182
- return _patterns
183
182
  elif RuleType.MULTI == self.rule_type and 2 == len(_values) \
184
183
  or self.rule_type in (RuleType.PATTERN, RuleType.PEM_KEY) and 0 < len(_values):
185
184
  for value in _values:
@@ -188,8 +187,9 @@ class Rule:
188
187
  logger.warning(f"Rule {self.rule_name} has extra patterns. Only single pattern supported.")
189
188
  elif RuleType.MULTI == self.rule_type and 2 < len(_values):
190
189
  logger.warning(f"Rule {self.rule_name} has extra patterns. Only two patterns supported.")
191
- return _patterns
192
- raise ValueError(f"Malformed rule config file. Rule '{self.rule_name}' type '{self.rule_type}' is invalid.")
190
+ else:
191
+ raise ValueError(f"Malformed rule config file. Rule '{self.rule_name}' type '{self.rule_type}' is invalid.")
192
+ return _patterns
193
193
 
194
194
  @cached_property
195
195
  def patterns(self) -> List[re.Pattern]:
@@ -1,5 +1,5 @@
1
1
  import statistics
2
- from typing import Tuple
2
+ from typing import Tuple, Dict
3
3
 
4
4
 
5
5
  class HopStat:
@@ -62,7 +62,7 @@ class HopStat:
62
62
  })
63
63
 
64
64
  def __init__(self):
65
- self.__hop_dict = dict()
65
+ self.__hop_dict: Dict[Tuple[str, str], int] = {}
66
66
  base = ''.join(x for x in HopStat.KEYBOARD)
67
67
  for a in (x for x in base if '\0' != x):
68
68
  for b in (x for x in base if '\0' != x):
@@ -81,7 +81,7 @@ class HopStat:
81
81
  def __get_xyz(c: str) -> Tuple[int, int, int]:
82
82
  """Returns axial coordinates of a char on keyboad qwerty"""
83
83
  x = y = z = 0
84
- for i in range(len(HopStat.KEYBOARD)):
84
+ for i, _ in enumerate(HopStat.KEYBOARD):
85
85
  x = HopStat.KEYBOARD[i].find(c)
86
86
  if 0 <= x:
87
87
  z = i
@@ -4,7 +4,7 @@ import re
4
4
  import string
5
5
  from typing import List
6
6
 
7
- from credsweeper.common.constants import PEM_BEGIN_PATTERN, PEM_END_PATTERN, ENTROPY_LIMIT_BASE64
7
+ from credsweeper.common.constants import PEM_BEGIN_PATTERN, PEM_END_PATTERN
8
8
  from credsweeper.config import Config
9
9
  from credsweeper.credentials import LineData
10
10
  from credsweeper.file_handler.analysis_target import AnalysisTarget
@@ -12,6 +12,8 @@ from credsweeper.utils import Util
12
12
 
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
+ ENTROPY_LIMIT_BASE64 = 4.5
16
+
15
17
 
16
18
  class PemKeyDetector:
17
19
  """Class to detect PEM PRIVATE keys only"""
@@ -64,7 +66,7 @@ class PemKeyDetector:
64
66
  if PEM_BEGIN_PATTERN in subline:
65
67
  begin_pattern_not_passed = False
66
68
  continue
67
- elif PEM_END_PATTERN in subline:
69
+ if PEM_END_PATTERN in subline:
68
70
  if "PGP" in target.line_strip:
69
71
  # Check if entropy is high enough for base64 set with padding sign
70
72
  entropy = Util.get_shannon_entropy(key_data)
@@ -124,7 +126,7 @@ class PemKeyDetector:
124
126
  line = line.strip(string.whitespace)
125
127
  if line.startswith("//"):
126
128
  # simplify first condition for speed-up of doxygen style processing
127
- if line.startswith("// ") or line.startswith("/// "):
129
+ if line.startswith(("// ", "/// ")):
128
130
  # Assume that the commented line is to be separated from base64 code, it may be a part of PEM, otherwise
129
131
  line = line[3:]
130
132
  if line.startswith("/*"):
credsweeper/utils/util.py CHANGED
@@ -170,9 +170,9 @@ class Util:
170
170
  else:
171
171
  return False
172
172
 
173
- NOT_LATIN1_PRINTABLE_SET = (set(range(0,
174
- 256)).difference(set(x for x in string.printable.encode(ASCII))).difference(
175
- set(x for x in range(0xA0, 0x100))))
173
+ NOT_LATIN1_PRINTABLE_SET = set(range(0, 256)) \
174
+ .difference(set(x for x in string.printable.encode(ASCII))) \
175
+ .difference(set(x for x in range(0xA0, 0x100)))
176
176
 
177
177
  @staticmethod
178
178
  def is_latin1(data: Union[bytes, bytearray]) -> bool:
@@ -229,7 +229,7 @@ class Util:
229
229
  if binary_suggest and LATIN_1 == encoding and (Util.is_binary(content) or not Util.is_latin1(content)):
230
230
  # LATIN_1 may convert data (bytes in range 0x80:0xFF are transformed)
231
231
  # so skip this encoding when checking binaries
232
- logger.warning("Binary file detected")
232
+ logger.warning("Binary file detected %s", repr(content[:8]))
233
233
  break
234
234
  text = content.decode(encoding, errors="strict")
235
235
  if content != text.encode(encoding, errors="strict"):
@@ -419,6 +419,13 @@ class Util:
419
419
  logger.exception(f"Corrupted TAR ? {exc}")
420
420
  return False
421
421
 
422
+ @staticmethod
423
+ def is_deb(data: Union[bytes, bytearray]) -> bool:
424
+ """According https://en.wikipedia.org/wiki/Deb_(file_format)"""
425
+ if isinstance(data, (bytes, bytearray)) and 512 <= len(data) and data.startswith(b"!<arch>\n"):
426
+ return True
427
+ return False
428
+
422
429
  @staticmethod
423
430
  def is_bzip2(data: Union[bytes, bytearray]) -> bool:
424
431
  """According https://en.wikipedia.org/wiki/Bzip2"""
@@ -458,7 +465,7 @@ class Util:
458
465
  def is_lzma(data: Union[bytes, bytearray]) -> bool:
459
466
  """According https://en.wikipedia.org/wiki/List_of_file_signatures - lzma also xz"""
460
467
  if isinstance(data, (bytes, bytearray)) and 6 <= len(data):
461
- if data.startswith(b"\xFD\x37\x7A\x58\x5A\x00") or data.startswith(b"\x5D\x00\x00"):
468
+ if data.startswith((b"\xFD\x37\x7A\x58\x5A\x00", b"\x5D\x00\x00")):
462
469
  return True
463
470
  return False
464
471
 
@@ -470,7 +477,7 @@ class Util:
470
477
  if 0x30 == data[0]:
471
478
  # https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/basic-encoding-rules.html#Lengths
472
479
  length = data[1]
473
- byte_len = (0x7F & length)
480
+ byte_len = 0x7F & length
474
481
  if 0x80 == length and data.endswith(b"\x00\x00"):
475
482
  return True
476
483
  elif 0x80 < length and 1 < byte_len < len(data): # additional check
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: credsweeper
3
- Version: 1.11.3
3
+ Version: 1.11.4
4
4
  Summary: Credential Sweeper
5
5
  Project-URL: Homepage, https://github.com/Samsung/CredSweeper
6
6
  Project-URL: Bug Tracker, https://github.com/Samsung/CredSweeper/issues
@@ -1,9 +1,9 @@
1
- credsweeper/__init__.py,sha256=L-vND0eGgSHFmpgZGvaEciE_TKM0FcH5DDa2yQdb9gQ,632
2
- credsweeper/__main__.py,sha256=iYL8byo3Ytq_RYqhF8kS4bFKzTGltDj93PCYGwZ72ZA,17244
3
- credsweeper/app.py,sha256=M0f6G97lsF2JALkr4IwQEKSZ__JicJGhOrgNmNDanyQ,21633
1
+ credsweeper/__init__.py,sha256=Kh5HJmZmdrYy5XuyYNC8hcpC-XYW4K5yFRu465rMoBs,632
2
+ credsweeper/__main__.py,sha256=W8T3LHhTjzdsn7tYXX9_cPRfgnNX1_Qr02Mw_s2IfQM,17221
3
+ credsweeper/app.py,sha256=GSKNb-sR7N4qTnZAyDsYVLmQm0zVMyQb4fQrxYLJfsk,20917
4
4
  credsweeper/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  credsweeper/common/__init__.py,sha256=mYiHEDV0hSeWcFx0Wb8oIRDCPR92ben0mCuC9-gCTgI,184
6
- credsweeper/common/constants.py,sha256=plBHrIVfj4CBpymIgLxTPiYr66_By3QKlgCoHYVKPLc,5534
6
+ credsweeper/common/constants.py,sha256=ZCE5VCpCMx1qmhVEfh2VYmjofQfaYzVip-ej0qJEPT8,5475
7
7
  credsweeper/common/keyword_checklist.py,sha256=6EKNdMMryZykedAOhEc-MF1byi5oXmAiljq61T_nco4,2258
8
8
  credsweeper/common/keyword_checklist.txt,sha256=a8GW-wF6D83uVFYxMWEsUFlth6c1B_KDpF8_Xpj0mE8,7169
9
9
  credsweeper/common/keyword_pattern.py,sha256=ZBJshY8hEP8CUFWQIrqQHcSLwPnUBTblNgFMOEoYUCY,3285
@@ -14,18 +14,19 @@ credsweeper/credentials/__init__.py,sha256=bn7BEgGqKcwlCLi5-7_sXlBmIpK7s5RrNcG_e
14
14
  credsweeper/credentials/augment_candidates.py,sha256=0YGjpTYRWQpzJcxpvOt_ytKBOWtHkOdMIHbMnJX22Ag,802
15
15
  credsweeper/credentials/candidate.py,sha256=a6CNNKqCEnOm_EEHVFBPGOgqheXegvTDh1TWL_gT-KQ,5508
16
16
  credsweeper/credentials/candidate_group_generator.py,sha256=rN_c4-ogPz0h-z2aPgzbu0hUz68L69xfd9oyzkooTUc,1243
17
- credsweeper/credentials/candidate_key.py,sha256=uaO4YzDs-NdYg0sAM7F7x7uoSLHOitJTAOZYHgvxfYY,913
18
- credsweeper/credentials/credential_manager.py,sha256=CjZ4_fd-tK2hobxASOf5vTOPzdpGmzpJYqxCpt1_La0,4149
19
- credsweeper/credentials/line_data.py,sha256=dLP-zViA7nfPVPn5b4HlK4-a6sdeD7FWJDluCsXKG9w,20647
17
+ credsweeper/credentials/candidate_key.py,sha256=NsYGPqqjfm6z2MGtcQbiUGiWmKUCuzflXlZYf_vn_84,917
18
+ credsweeper/credentials/credential_manager.py,sha256=cHEfIs2xb3n400D5Q6AC5CDM9jzzK_Fcb-VKVRh_H2U,4187
19
+ credsweeper/credentials/line_data.py,sha256=8-9sgK3n1gMg_L63Ked8f5PlIpimWTqnYCNCEmx6WZ0,20622
20
20
  credsweeper/deep_scanner/__init__.py,sha256=Lp94BjQPZTgEa77E0v6xZaXZvQf2A-QTHsjqCzZxUFw,62
21
21
  credsweeper/deep_scanner/abstract_scanner.py,sha256=fVS-IuR_9A2vVmAiEzlMund3VnrTOZv4bAXvIUgB11k,1725
22
22
  credsweeper/deep_scanner/byte_scanner.py,sha256=oHeA8mGe995SHqWvONhTDBIE5j50TQASHA9Mv6LHYuQ,1125
23
23
  credsweeper/deep_scanner/bzip2_scanner.py,sha256=74RsjmeuffEuxmKl04lXIZt3q_Zvxj-gLHXACqVSU_o,1619
24
- credsweeper/deep_scanner/deep_scanner.py,sha256=OQzMAs78vFJl2rZlIxu-puhv-ssToWigZlMTMPFXndY,17936
24
+ credsweeper/deep_scanner/deb_scanner.py,sha256=9RshNYbPbUTHPskzk0tcl6bSodYtfdZo8OW7Ize6j74,2159
25
+ credsweeper/deep_scanner/deep_scanner.py,sha256=FW-vhIHnE37Mo3pWmVt0vHK71lUghMcG6tIuWO_Vjok,18720
25
26
  credsweeper/deep_scanner/docx_scanner.py,sha256=_xIuw5SkGU1wO_9C3fXVycM-iSmU9qUzWa53etuFvMI,4153
26
27
  credsweeper/deep_scanner/eml_scanner.py,sha256=iRLr2yvBWGktT2oXxl-haqnhJN3tglO1Mej10hFk0as,3512
27
28
  credsweeper/deep_scanner/encoder_scanner.py,sha256=ULv9AgfG_ZLCYYgyUeQicna9u1i-rlmOiE4euvqahmY,1315
28
- credsweeper/deep_scanner/gzip_scanner.py,sha256=jIOHZ9oYBV_LIzJjY5JU6NgbGhrLg2rbOYp3X-iv4QU,1696
29
+ credsweeper/deep_scanner/gzip_scanner.py,sha256=DwG3rSC2YxvE6aTiSKDXoqMSM1wCag_1AX2NYnDQYTM,1695
29
30
  credsweeper/deep_scanner/html_scanner.py,sha256=Mh6gUxvlMnI4Kys7V8ZBBExQSsOYqYUbil7FYiXX4lc,1486
30
31
  credsweeper/deep_scanner/jks_scanner.py,sha256=1BqHfOmqcznrhMN-9aH-L8yamIAj72OYr7_DBuuj0_c,1867
31
32
  credsweeper/deep_scanner/lang_scanner.py,sha256=6d_n3Gjj8HPvNayalDn48QGbRMofmOwFUyS6V8JQsVU,1340
@@ -42,17 +43,17 @@ credsweeper/deep_scanner/zip_scanner.py,sha256=rWNV43OV8FTpXGMkAlRCwnnaJ-WdiIpre
42
43
  credsweeper/file_handler/__init__.py,sha256=fAQvFQvgPQ7lAPVjPWmAdKArRCS5pB4QEk01jkVVB-E,662
43
44
  credsweeper/file_handler/abstract_provider.py,sha256=sl0XrlbRDak885UzD7HBruXAD9vJHso-glqI_ekZxuo,1437
44
45
  credsweeper/file_handler/analysis_target.py,sha256=FEznSNcUbTaqGa3ZKy8FusdqDR7CxFX1fwIrA_LdwoY,2752
45
- credsweeper/file_handler/byte_content_provider.py,sha256=o_oNK6ovAhKJGw8C4gDDYrtqMQ_ErsEL5_HVOjshEi4,1926
46
- credsweeper/file_handler/content_provider.py,sha256=ZMhEa83HZHGFTNhFVq_qhdd00GLYm6vlybk9XIk7EQc,3890
47
- credsweeper/file_handler/data_content_provider.py,sha256=r2mUG4iwPwOmwfIU05Ei4SvN7JC1vYiYBWWrEeYoQYg,17665
46
+ credsweeper/file_handler/byte_content_provider.py,sha256=aqYndCeDSF1BLEYUzwcl3BASuuUr1vlU6l-Eo73eEw4,1930
47
+ credsweeper/file_handler/content_provider.py,sha256=HYlAL1wRZeQe49upKt4_Y00Gsja88jWKeIeNbkm2hR0,3888
48
+ credsweeper/file_handler/data_content_provider.py,sha256=g1eDo7Ic5fjWdo6k7DYDvz4n5BAnUmBZM35phi9bUp8,17669
48
49
  credsweeper/file_handler/descriptor.py,sha256=LQHjzmRL0fl8mlKwA--Nl_D4mKFtg9VsUJnWZqtjFhU,185
49
- credsweeper/file_handler/diff_content_provider.py,sha256=-gwyWJU62F0EpiUP5HH1WgaoP2_e3nRA0Fu4he6YcVQ,3209
50
- credsweeper/file_handler/file_path_extractor.py,sha256=I_gPZSw1s-QSsa0ynVEfveGvRyHqVAifYk4V76pWcHo,6907
51
- credsweeper/file_handler/files_provider.py,sha256=YiRHzGocdexXd3qgMEwkqahMMUrN5gc0ivOEUCjD1_U,2652
52
- credsweeper/file_handler/patches_provider.py,sha256=BWIxWsEYwwWGPweA6BrKP3q412kzmJOm1g8bhCrk4B4,2885
53
- credsweeper/file_handler/string_content_provider.py,sha256=OlLF-c40zGkCulPZwzHfTElF65Z7G3XKQfpCe5aBKLw,2477
54
- credsweeper/file_handler/struct_content_provider.py,sha256=_RfQ_JEJprn5haOLlzAYwabCHT4Pdm8VXc3KhTwaQ40,1593
55
- credsweeper/file_handler/text_content_provider.py,sha256=FHzwtlPsRHBJwHW0p9AumPe-iTv671K-N7A5QlSolDM,2999
50
+ credsweeper/file_handler/diff_content_provider.py,sha256=FtlHa7Y5LrXrzQNFOeRhVqQjtbWe0m82wmXHHjPXntw,3209
51
+ credsweeper/file_handler/file_path_extractor.py,sha256=lSwbl2Q4eTEo8U-SghzijoFL6H0q3W7LtE-iGF3Qkvg,6889
52
+ credsweeper/file_handler/files_provider.py,sha256=qpaIQw9JWGrxv-mQyD_1KPoWppyaZYaBoZJDt3DykFU,2569
53
+ credsweeper/file_handler/patches_provider.py,sha256=3N5U0J2-7p6fckLQNHqly6bnuU5KawlX3qpbAPmkVbk,2862
54
+ credsweeper/file_handler/string_content_provider.py,sha256=e7mHLwa5bkHthI3hr5pP7ZlyoFfPeeVbmTAlZG2-xB4,2481
55
+ credsweeper/file_handler/struct_content_provider.py,sha256=H1ZhSosaWJEOtzWYC1rve0glrJUu2UDYjmOx-9DDNxs,1595
56
+ credsweeper/file_handler/text_content_provider.py,sha256=5Qg_4LIYB3O4MZo4Gqtno4o8rPU2hPy6tOR_7wS87Kw,3003
56
57
  credsweeper/filters/__init__.py,sha256=EwLbbc2pXwAhSSJx0QXBcujRkP4Py6Fnf3MNm6ZkngQ,3267
57
58
  credsweeper/filters/filter.py,sha256=CqZbTsIDNVVwQyOjNekgNr_i1nPS4foutm0AvGAjM5M,826
58
59
  credsweeper/filters/line_git_binary_check.py,sha256=G5N-woSLXC1mdiD80AhXbOpJCjGwtvFwFwMmRu87qlY,1595
@@ -64,7 +65,7 @@ credsweeper/filters/value_atlassian_token_check.py,sha256=rAuMC5JUxnXZwPxoKtrwFV
64
65
  credsweeper/filters/value_azure_token_check.py,sha256=GlIqmzinjtQ4GU8-_ZyFTM2uo1ylRxRFKqnJaW_0110,1946
65
66
  credsweeper/filters/value_base32_data_check.py,sha256=nS_X5vb5e0fXnjxGjyGE9wedmAj6B14AG8dEjRClREQ,1390
66
67
  credsweeper/filters/value_base64_data_check.py,sha256=J5dMgJsfs13MxijOMqGLYU8PZz5eEDUBrWVKp0mE3T0,1449
67
- credsweeper/filters/value_base64_encoded_pem_check.py,sha256=sX80Uo_7b7HQm4KjNkRHqB8FQvxuuvMLhxAUalSQeaU,1607
68
+ credsweeper/filters/value_base64_encoded_pem_check.py,sha256=k7J6FY3SCdgnHRkoSCPMKcUgyTOOTl4t4tHZI6hvSiA,1600
68
69
  credsweeper/filters/value_base64_key_check.py,sha256=6JrIGNphjM9gN8oi1OKyvm4MUvvLxsQPxGP5BkaTC1w,2131
69
70
  credsweeper/filters/value_base64_part_check.py,sha256=wV_qGv9xK4H8EB903Qw5xbVtjAQ19ZZKhhHFoQ53AT8,4958
70
71
  credsweeper/filters/value_blocklist_check.py,sha256=CSsD68QRF1zFLM2MB5pGRRs95O8IepZ9AUZYdxlBf-c,1145
@@ -75,7 +76,7 @@ credsweeper/filters/value_dictionary_value_length_check.py,sha256=lQj6pmKitFJXqB
75
76
  credsweeper/filters/value_discord_bot_check.py,sha256=Zv8SIkYGvd2mn6MGo4JGH-amGnJJBXqa992aQ9ZXlK4,1480
76
77
  credsweeper/filters/value_entropy_base32_check.py,sha256=PKFp6eOXZ8yiK00JNxWPbxw4LnAeE16u39ePNozTGEg,642
77
78
  credsweeper/filters/value_entropy_base36_check.py,sha256=ZHa_AUtskBCmfhUQwjgkolB1OuB2t1GRDi8SDl7o_A8,651
78
- credsweeper/filters/value_entropy_base64_check.py,sha256=7q-lGKp0SvWz4ZE_iD2aajVkIU6CtYaxRuyye2VLdh0,908
79
+ credsweeper/filters/value_entropy_base64_check.py,sha256=Kp6AU1rOqEnO4MJ7xoQhMSbvoJKMBBcEQvZz_JsX_kY,812
79
80
  credsweeper/filters/value_entropy_base_check.py,sha256=Z4ymeTPs5tPL37BtQQe05yp6kyY8c_caYZXwpOF9-ZU,1241
80
81
  credsweeper/filters/value_file_path_check.py,sha256=2hwqr2xCwzuL6Ya6X1uyClQld0RSMBGRJvAJCKPcRzw,3512
81
82
  credsweeper/filters/value_github_check.py,sha256=nRYvTxvhFo2PCMwneg5K4I7gJ3tBNzOOYDEhun0pxwg,1441
@@ -89,7 +90,7 @@ credsweeper/filters/value_method_check.py,sha256=mkTmSGnQBKtELTpNrKh6v_5VyORrVLV
89
90
  credsweeper/filters/value_not_allowed_pattern_check.py,sha256=Hq0ToZ_XL70N4CAwbSG0XD9mRTsqIhTqgT5YWlgfwwg,1178
90
91
  credsweeper/filters/value_not_part_encoded_check.py,sha256=LyebBZlR1aXFkOSDOq1jnqJKLDmEI8nHr5OXa3J09b0,3805
91
92
  credsweeper/filters/value_number_check.py,sha256=UxRQ24XFKPpEbpkOH3_YgrrBSBTeP9WwYRGWB9Ez-V0,1130
92
- credsweeper/filters/value_pattern_check.py,sha256=OJLm6h7nIXjrN0JMgh3e49_WZo8hwGdaTcz9nd6VKgE,3998
93
+ credsweeper/filters/value_pattern_check.py,sha256=sPl2c_bmucUj4VCBgAHM6q4YixQcfrjrJR0HDmmIFKM,5375
93
94
  credsweeper/filters/value_similarity_check.py,sha256=qa2NPSpyP8RIqllXIlky66Bk85PDU2ss_dQW-vcm3Qw,1172
94
95
  credsweeper/filters/value_split_keyword_check.py,sha256=MY-EZmHSYzuglxVug9MQYtwWlMTAAwr1L3lyaOaT6VE,1113
95
96
  credsweeper/filters/value_string_type_check.py,sha256=QmgniKlNTPKB4fLrvj9QxMmt8yQkmB9gxtZv50J4YYI,1985
@@ -112,11 +113,11 @@ credsweeper/logger/logger.py,sha256=E427IHUgX5jOCUKYlXKwQiyXNIUSYBpP45ldNCfVjFw,
112
113
  credsweeper/ml_model/__init__.py,sha256=Bvw_WgOmNwzFrBP0tKgWapasYcU7IRT0zMpbmWD6DwU,58
113
114
  credsweeper/ml_model/ml_config.json,sha256=QDPNRl-QT9TY7NPgOjjsekDdPvxI3IZkyXcr5VSa6eY,16049
114
115
  credsweeper/ml_model/ml_model.onnx,sha256=1z_vsA2d74qvEUfDDxGGsWmUvRLotd7AM1C7QlkO1bE,10979845
115
- credsweeper/ml_model/ml_validator.py,sha256=DcvoRh361ussH7YfUcqdE4EqCCqxpC0G0_ofGVVbRLw,11924
116
+ credsweeper/ml_model/ml_validator.py,sha256=ROAMlC394DCVNqqXxqT8y-jbx9y1oKuWY9yMvzFJjZI,12881
116
117
  credsweeper/ml_model/features/__init__.py,sha256=OtWcKTbXsM4hi4P8G6f-T_FC6pQVOz_le2FbN2Kak1c,1020
117
118
  credsweeper/ml_model/features/entropy_evaluation.py,sha256=Mzv6bSui2XbX-WBLHk0gI0x_9RHgRjM7n9ep0VfDCIw,2605
118
119
  credsweeper/ml_model/features/feature.py,sha256=6qYXKh1vDC0rgFn1zrXsCbr52W4r3jL6Ju1UUECBPWY,1094
119
- credsweeper/ml_model/features/file_extension.py,sha256=aHtoatjQ9YkKd47Y-3HEDn4-JrCuRmaxmcnPhXqX60Y,694
120
+ credsweeper/ml_model/features/file_extension.py,sha256=9kpw5bIk4i6vUZlcw8LMSivViSK_Y1u7crQsIuWcsOk,692
120
121
  credsweeper/ml_model/features/has_html_tag.py,sha256=ZvcW1gU1_v9iMjb4ho1a3jHbWioOxtggCc1ZqmtSWl8,1116
121
122
  credsweeper/ml_model/features/is_secret_numeric.py,sha256=eSI2glS_WdFuozX5E7YbFoF7gZlFHu1zj4dd8nJpSrk,401
122
123
  credsweeper/ml_model/features/length_of_attribute.py,sha256=8H4Zc1mOjGXV5mwZkjvCt7xKKiiKPIEJDBhdlz8j3PE,1192
@@ -131,8 +132,8 @@ credsweeper/ml_model/features/word_in_transition.py,sha256=SgG8D37lXnDaFOKagi9lb
131
132
  credsweeper/ml_model/features/word_in_value.py,sha256=QCVJRpcqEg-xC9a94fppqQbvReQLZSHNi0Zrtmr9Ul0,571
132
133
  credsweeper/ml_model/features/word_in_variable.py,sha256=aETM5N2AF7FJhmrzLYDvMpKt-K1D8J0ZULxsgSRMXPU,534
133
134
  credsweeper/rules/__init__.py,sha256=alXS8IivUs-AKKbVHiWvSjFpg1urJZLKItuFr61HHyg,40
134
- credsweeper/rules/config.yaml,sha256=UpeAYbZWulS1TV2eRDv2jor1s9Jndi15DHmV-6hQWiM,38281
135
- credsweeper/rules/rule.py,sha256=rU6vJ4cVoeAZdUMWalRTMuAdRuYgFxeTltvSYUJRHOU,10224
135
+ credsweeper/rules/config.yaml,sha256=0Ub-P7wSzKABcJsO2fv3TQE1qPOnMsiExdzUk6SqVAc,38297
136
+ credsweeper/rules/rule.py,sha256=JyK712m75E4ALxq7gEh_ex_b0MZvC0Bw2_2pzeAoLFY,10209
136
137
  credsweeper/scanner/__init__.py,sha256=KUh1uUEgZOd12DiXV-TQP3OvByI9tsyqN1KCdw994h8,48
137
138
  credsweeper/scanner/scanner.py,sha256=2znRjqV9Mx4D0z9elUslOQIoLbfDybu1hF1TEaRzTkc,10127
138
139
  credsweeper/scanner/scan_type/__init__.py,sha256=JHOdDZv5bmGsj0dhIiApvjcFzQ8LYkCQdWmhxAs4lgI,288
@@ -143,11 +144,11 @@ credsweeper/scanner/scan_type/single_pattern.py,sha256=TCbjbeK0NrWzU6eBMZqHjYXo3
143
144
  credsweeper/secret/config.json,sha256=7pZiSBQtINsgE3Qc8V9peznH5wBCzSmkrZaVZLuWVe8,3504
144
145
  credsweeper/secret/log.yaml,sha256=h29atN5Kvk68oKuTYG2Mi4f2uNO3dvwhOkzCRBKo1rg,952
145
146
  credsweeper/utils/__init__.py,sha256=wPdTkrSBAkR3rppFZ68k6MiT_P7tIHuAb3AcwndJCWg,63
146
- credsweeper/utils/hop_stat.py,sha256=0D7xB1CVAUhseOZWvLZXxn3MYHKZnfnFJ8hj7tONiyU,2978
147
- credsweeper/utils/pem_key_detector.py,sha256=JQex5KxQfWBP7SvhX2qf6tlQcma9a9yvsvDJX13EZe0,7633
148
- credsweeper/utils/util.py,sha256=Me-fEpM8hQPERl-YV1MN2B-NARHTLwE1obSiqZq3h68,28730
149
- credsweeper-1.11.3.dist-info/METADATA,sha256=PvTMsbARLWplOGHVaz4LwYgaO0IDruIsqlfo2azA_gE,10504
150
- credsweeper-1.11.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
151
- credsweeper-1.11.3.dist-info/entry_points.txt,sha256=SLGNZshvi3zpWPhVmRP-oDXRMRPBS4tzRDy6xYOXwqA,58
152
- credsweeper-1.11.3.dist-info/licenses/LICENSE,sha256=aU7mGjBKbmRHNLVXXzcPdKmTtBxRwDPtjflQRfN7fFg,1065
153
- credsweeper-1.11.3.dist-info/RECORD,,
147
+ credsweeper/utils/hop_stat.py,sha256=vMd_1lcpDo4yaFhi61X0tJeeE83qUbzPckvxZcrgsgs,3010
148
+ credsweeper/utils/pem_key_detector.py,sha256=I8IlUkae6FVPMbr47JdwJ6jIMixf6diwyzQO1BEBclM,7620
149
+ credsweeper/utils/util.py,sha256=qLMYVl2mvzDTE8DtbJhCY154G_ix9J4mso1vPgKfvew,28959
150
+ credsweeper-1.11.4.dist-info/METADATA,sha256=L4XFeUBh6juiW3QIwQD5szunVXfjCXmDlVcpBjY7-as,10504
151
+ credsweeper-1.11.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
152
+ credsweeper-1.11.4.dist-info/entry_points.txt,sha256=SLGNZshvi3zpWPhVmRP-oDXRMRPBS4tzRDy6xYOXwqA,58
153
+ credsweeper-1.11.4.dist-info/licenses/LICENSE,sha256=aU7mGjBKbmRHNLVXXzcPdKmTtBxRwDPtjflQRfN7fFg,1065
154
+ credsweeper-1.11.4.dist-info/RECORD,,