credsweeper 1.10.5__tar.gz → 1.10.7__tar.gz

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 (150) hide show
  1. {credsweeper-1.10.5 → credsweeper-1.10.7}/PKG-INFO +2 -2
  2. {credsweeper-1.10.5 → credsweeper-1.10.7}/README.md +1 -1
  3. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/__init__.py +1 -1
  4. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/__main__.py +29 -9
  5. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/app.py +18 -10
  6. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/common/keyword_pattern.py +22 -15
  7. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/credentials/credential_manager.py +14 -6
  8. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_allowlist_check.py +24 -8
  9. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_blocklist_check.py +3 -0
  10. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_token_base_check.py +3 -4
  11. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/rules/config.yaml +16 -0
  12. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/utils/hop_stat.py +27 -1
  13. {credsweeper-1.10.5 → credsweeper-1.10.7}/.gitignore +0 -0
  14. {credsweeper-1.10.5 → credsweeper-1.10.7}/LICENSE +0 -0
  15. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/common/__init__.py +0 -0
  16. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/common/constants.py +0 -0
  17. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/common/keyword_checklist.py +0 -0
  18. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/common/keyword_checklist.txt +0 -0
  19. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/common/morpheme_checklist.txt +0 -0
  20. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/config/__init__.py +0 -0
  21. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/config/config.py +0 -0
  22. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/credentials/__init__.py +0 -0
  23. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/credentials/augment_candidates.py +0 -0
  24. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/credentials/candidate.py +0 -0
  25. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/credentials/candidate_group_generator.py +0 -0
  26. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/credentials/candidate_key.py +0 -0
  27. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/credentials/line_data.py +0 -0
  28. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/__init__.py +0 -0
  29. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/abstract_scanner.py +0 -0
  30. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/byte_scanner.py +0 -0
  31. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/bzip2_scanner.py +0 -0
  32. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/deep_scanner.py +0 -0
  33. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/docx_scanner.py +0 -0
  34. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/eml_scanner.py +0 -0
  35. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/encoder_scanner.py +0 -0
  36. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/gzip_scanner.py +0 -0
  37. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/html_scanner.py +0 -0
  38. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/jks_scanner.py +0 -0
  39. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/lang_scanner.py +0 -0
  40. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/mxfile_scanner.py +0 -0
  41. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/pdf_scanner.py +0 -0
  42. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/pkcs12_scanner.py +0 -0
  43. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/pptx_scanner.py +0 -0
  44. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/tar_scanner.py +0 -0
  45. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/xlsx_scanner.py +0 -0
  46. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/xml_scanner.py +0 -0
  47. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/deep_scanner/zip_scanner.py +0 -0
  48. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/__init__.py +0 -0
  49. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/abstract_provider.py +0 -0
  50. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/analysis_target.py +0 -0
  51. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/byte_content_provider.py +0 -0
  52. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/content_provider.py +0 -0
  53. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/data_content_provider.py +0 -0
  54. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/descriptor.py +0 -0
  55. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/diff_content_provider.py +0 -0
  56. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/file_path_extractor.py +0 -0
  57. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/files_provider.py +0 -0
  58. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/patches_provider.py +0 -0
  59. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/string_content_provider.py +0 -0
  60. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/struct_content_provider.py +0 -0
  61. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/file_handler/text_content_provider.py +0 -0
  62. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/__init__.py +0 -0
  63. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/filter.py +0 -0
  64. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/__init__.py +0 -0
  65. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/general_keyword.py +0 -0
  66. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/general_pattern.py +0 -0
  67. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/group.py +0 -0
  68. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/password_keyword.py +0 -0
  69. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/token_pattern.py +0 -0
  70. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/url_credentials_group.py +0 -0
  71. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/weird_base36_token.py +0 -0
  72. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/group/weird_base64_token.py +0 -0
  73. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/line_git_binary_check.py +0 -0
  74. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/line_specific_key_check.py +0 -0
  75. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/line_uue_part_check.py +0 -0
  76. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_array_dictionary_check.py +0 -0
  77. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_atlassian_token_check.py +0 -0
  78. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_azure_token_check.py +0 -0
  79. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_base32_data_check.py +0 -0
  80. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_base64_data_check.py +0 -0
  81. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_base64_encoded_pem_check.py +0 -0
  82. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_base64_key_check.py +0 -0
  83. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_base64_part_check.py +0 -0
  84. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_camel_case_check.py +0 -0
  85. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_couple_keyword_check.py +0 -0
  86. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_dictionary_keyword_check.py +0 -0
  87. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_dictionary_value_length_check.py +0 -0
  88. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_discord_bot_check.py +0 -0
  89. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_entropy_base32_check.py +0 -0
  90. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_entropy_base36_check.py +0 -0
  91. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_entropy_base64_check.py +0 -0
  92. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_file_path_check.py +0 -0
  93. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_first_word_check.py +0 -0
  94. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_github_check.py +0 -0
  95. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_grafana_check.py +0 -0
  96. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_grafana_service_check.py +0 -0
  97. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_hex_number_check.py +0 -0
  98. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_jfrog_token_check.py +0 -0
  99. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_json_web_token_check.py +0 -0
  100. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_last_word_check.py +0 -0
  101. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_method_check.py +0 -0
  102. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_not_allowed_pattern_check.py +0 -0
  103. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_not_part_encoded_check.py +0 -0
  104. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_number_check.py +0 -0
  105. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_pattern_check.py +0 -0
  106. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_similarity_check.py +0 -0
  107. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_split_keyword_check.py +0 -0
  108. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_string_type_check.py +0 -0
  109. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_token_base32_check.py +0 -0
  110. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_token_base36_check.py +0 -0
  111. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_token_base64_check.py +0 -0
  112. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/filters/value_token_check.py +0 -0
  113. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/logger/__init__.py +0 -0
  114. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/logger/logger.py +0 -0
  115. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/__init__.py +0 -0
  116. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/__init__.py +0 -0
  117. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/entropy_evaluation.py +0 -0
  118. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/feature.py +0 -0
  119. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/file_extension.py +0 -0
  120. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/has_html_tag.py +0 -0
  121. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/is_secret_numeric.py +0 -0
  122. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/length_of_attribute.py +0 -0
  123. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/morpheme_dense.py +0 -0
  124. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/rule_name.py +0 -0
  125. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/search_in_attribute.py +0 -0
  126. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/word_in.py +0 -0
  127. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/word_in_line.py +0 -0
  128. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/word_in_path.py +0 -0
  129. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/word_in_value.py +0 -0
  130. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/features/word_in_variable.py +0 -0
  131. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/ml_config.json +0 -0
  132. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/ml_model.onnx +0 -0
  133. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/ml_model/ml_validator.py +0 -0
  134. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/py.typed +0 -0
  135. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/rules/__init__.py +0 -0
  136. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/rules/rule.py +0 -0
  137. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/scanner/__init__.py +0 -0
  138. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/scanner/scan_type/__init__.py +0 -0
  139. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/scanner/scan_type/multi_pattern.py +0 -0
  140. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/scanner/scan_type/pem_key_pattern.py +0 -0
  141. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/scanner/scan_type/scan_type.py +0 -0
  142. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/scanner/scan_type/single_pattern.py +0 -0
  143. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/scanner/scanner.py +0 -0
  144. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/secret/config.json +0 -0
  145. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/secret/log.yaml +0 -0
  146. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/utils/__init__.py +0 -0
  147. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/utils/entropy_validator.py +0 -0
  148. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/utils/pem_key_detector.py +0 -0
  149. {credsweeper-1.10.5 → credsweeper-1.10.7}/credsweeper/utils/util.py +0 -0
  150. {credsweeper-1.10.5 → credsweeper-1.10.7}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: credsweeper
3
- Version: 1.10.5
3
+ Version: 1.10.7
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
@@ -87,7 +87,7 @@ Full documentation can be found here: <https://credsweeper.readthedocs.io/>
87
87
 
88
88
  ### Main Requirements
89
89
 
90
- - Python 3.8, 3.9, 3.10, 3.11, 3.12
90
+ - Python 3.9, 3.10, 3.11, 3.12
91
91
 
92
92
  ### Installation
93
93
 
@@ -46,7 +46,7 @@ Full documentation can be found here: <https://credsweeper.readthedocs.io/>
46
46
 
47
47
  ### Main Requirements
48
48
 
49
- - Python 3.8, 3.9, 3.10, 3.11, 3.12
49
+ - Python 3.9, 3.10, 3.11, 3.12
50
50
 
51
51
  ### Installation
52
52
 
@@ -18,4 +18,4 @@ __all__ = [
18
18
  '__version__'
19
19
  ]
20
20
 
21
- __version__ = "1.10.5"
21
+ __version__ = "1.10.7"
@@ -3,7 +3,7 @@ import logging
3
3
  import os
4
4
  import sys
5
5
  import time
6
- from argparse import ArgumentParser, ArgumentTypeError, Namespace
6
+ from argparse import ArgumentParser, ArgumentTypeError, Namespace, BooleanOptionalAction
7
7
  from typing import Any, Union, Dict
8
8
 
9
9
  from credsweeper import __version__
@@ -205,12 +205,16 @@ def get_arguments() -> Namespace:
205
205
  metavar="POSITIVE_INT")
206
206
  parser.add_argument("--thrifty",
207
207
  help="clear objects after scan to reduce memory consumption",
208
- action="store_const",
209
- const=True)
208
+ action=BooleanOptionalAction,
209
+ default=True)
210
210
  parser.add_argument("--skip_ignored",
211
211
  help="parse .gitignore files and skip credentials from ignored objects",
212
212
  dest="skip_ignored",
213
213
  action="store_true")
214
+ parser.add_argument("--error",
215
+ help="produce error code if credentials are found",
216
+ action=BooleanOptionalAction,
217
+ default=False)
214
218
  parser.add_argument("--save-json",
215
219
  nargs="?",
216
220
  help="save result to json file (default: output.json)",
@@ -223,16 +227,21 @@ def get_arguments() -> Namespace:
223
227
  const="output.xlsx",
224
228
  dest="xlsx_filename",
225
229
  metavar="PATH")
226
- parser.add_argument("--color", "-C", help="print results with colorization", action="store_const", const=True)
230
+ parser.add_argument("--stdout", help="print results to stdout", action=BooleanOptionalAction, default=True)
231
+ parser.add_argument("--color", help="print results with colorization", action=BooleanOptionalAction, default=False)
227
232
  parser.add_argument("--hashed",
228
233
  help="line, variable, value will be hashed in output",
229
- action="store_const",
230
- const=True)
234
+ action=BooleanOptionalAction,
235
+ default=False)
231
236
  parser.add_argument("--subtext",
232
237
  help=f"line text will be stripped in {2 * ML_HUNK} symbols but value and variable are kept",
233
- action="store_const",
234
- const=True)
235
- parser.add_argument("--sort", help="enable output sorting", dest="sort_output", action="store_true")
238
+ action=BooleanOptionalAction,
239
+ default=False)
240
+ parser.add_argument("--sort",
241
+ help="enable output sorting",
242
+ dest="sort_output",
243
+ action=BooleanOptionalAction,
244
+ default=False)
236
245
  parser.add_argument("--log",
237
246
  "-l",
238
247
  help=f"provide logging level of {list(Logger.LEVELS.keys())}"
@@ -281,6 +290,7 @@ def scan(args: Namespace, content_provider: AbstractProvider) -> int:
281
290
  config_path=args.config_path,
282
291
  json_filename=args.json_filename,
283
292
  xlsx_filename=args.xlsx_filename,
293
+ stdout=args.stdout,
284
294
  color=args.color,
285
295
  hashed=args.hashed,
286
296
  subtext=args.subtext,
@@ -310,6 +320,7 @@ def scan(args: Namespace, content_provider: AbstractProvider) -> int:
310
320
  def main() -> int:
311
321
  """Main function"""
312
322
  result = EXIT_FAILURE
323
+ credentials_number = 0
313
324
  start_time = time.time()
314
325
  args = get_arguments()
315
326
  if args.banner:
@@ -336,15 +347,20 @@ def main() -> int:
336
347
  del_credentials_number = scan(args, content_provider)
337
348
  summary["Deleted File Credentials"] = del_credentials_number
338
349
  if 0 <= add_credentials_number and 0 <= del_credentials_number:
350
+ # it means the scan was successful done
339
351
  result = EXIT_SUCCESS
352
+ # collect number of all found credential to produce error code when necessary
353
+ credentials_number = add_credentials_number + del_credentials_number
340
354
  elif args.export_config:
341
355
  logging.info(f"Exporting default config to file: {args.export_config}")
342
356
  config_dict = Util.json_load(APP_PATH / "secret" / "config.json")
343
357
  Util.json_dump(config_dict, args.export_config)
358
+ result = EXIT_SUCCESS
344
359
  elif args.export_log_config:
345
360
  logging.info(f"Exporting default logger config to file: {args.export_log_config}")
346
361
  config_dict = Util.yaml_load(APP_PATH / "secret" / "log.yaml")
347
362
  Util.yaml_dump(config_dict, args.export_log_config)
363
+ result = EXIT_SUCCESS
348
364
  elif args.banner and 2 == len(sys.argv):
349
365
  # only extend version invocation
350
366
  result = EXIT_SUCCESS
@@ -357,6 +373,10 @@ def main() -> int:
357
373
  end_time = time.time()
358
374
  print(f"Time Elapsed: {end_time - start_time}s")
359
375
 
376
+ if args.error and EXIT_SUCCESS == result and 0 < credentials_number:
377
+ # override result when credentials were found with the requirement
378
+ result = EXIT_FAILURE
379
+
360
380
  return result
361
381
 
362
382
 
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import logging
2
3
  import multiprocessing
3
4
  import signal
@@ -41,6 +42,7 @@ class CredSweeper:
41
42
  config_path: Optional[str] = None,
42
43
  json_filename: Union[None, str, Path] = None,
43
44
  xlsx_filename: Union[None, str, Path] = None,
45
+ stdout: bool = False,
44
46
  color: bool = False,
45
47
  hashed: bool = False,
46
48
  subtext: bool = False,
@@ -70,7 +72,8 @@ class CredSweeper:
70
72
  default built-in config is used if None
71
73
  json_filename: optional string variable, path to save result to json
72
74
  xlsx_filename: optional string variable, path to save result to xlsx
73
- color: print results to stdout with colorization
75
+ stdout: print results to stdout
76
+ color: print concise results to stdout with colorization
74
77
  hashed: use hash of line, value and variable instead plain text
75
78
  subtext: use subtext of line near variable-value like it performed in ML
76
79
  use_filters: boolean variable, specifying the need of rule filters
@@ -110,6 +113,7 @@ class CredSweeper:
110
113
  self.credential_manager = CredentialManager()
111
114
  self.json_filename: Union[None, str, Path] = json_filename
112
115
  self.xlsx_filename: Union[None, str, Path] = xlsx_filename
116
+ self.stdout = stdout
113
117
  self.color = color
114
118
  self.hashed = hashed
115
119
  self.subtext = subtext
@@ -245,8 +249,7 @@ class CredSweeper:
245
249
  # PatchesProvider has the attribute. Circular import error appears with using the isinstance
246
250
  change_type = content_provider.change_type if hasattr(content_provider, "change_type") else None
247
251
  self.export_results(change_type)
248
-
249
- return len(self.credential_manager.get_credentials())
252
+ return self.credential_manager.len_credentials()
250
253
 
251
254
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
252
255
 
@@ -392,7 +395,6 @@ class CredSweeper:
392
395
  Args:
393
396
  change_type: flag to know which file should be created for a patch
394
397
  """
395
- is_exported = False
396
398
 
397
399
  credentials = self.credential_manager.get_credentials()
398
400
 
@@ -410,15 +412,22 @@ class CredSweeper:
410
412
 
411
413
  if self.json_filename:
412
414
  json_path = Path(self.json_filename)
413
- is_exported = True
414
415
  if isinstance(change_type, DiffRowType):
415
416
  # add suffix for appropriated reports to create two files for the patch scan
416
417
  json_path = json_path.with_suffix(f".{change_type.value}{json_path.suffix}")
417
- Util.json_dump([credential.to_json(hashed=self.hashed, subtext=self.subtext) for credential in credentials],
418
- file_path=json_path)
418
+ with open(json_path, 'w') as f:
419
+ # use the approach to reduce total memory usage in case of huge data
420
+ first_item = True
421
+ f.write('[\n')
422
+ for credential in credentials:
423
+ if first_item:
424
+ first_item = False
425
+ else:
426
+ f.write(",\n")
427
+ f.write(json.dumps(credential.to_json(hashed=self.hashed, subtext=self.subtext), indent=4))
428
+ f.write("\n]")
419
429
 
420
430
  if self.xlsx_filename:
421
- is_exported = True
422
431
  data_list = []
423
432
  for credential in credentials:
424
433
  data_list.extend(credential.to_dict_list(hashed=self.hashed, subtext=self.subtext))
@@ -434,7 +443,6 @@ class CredSweeper:
434
443
  df.to_excel(self.xlsx_filename, sheet_name="report", index=False)
435
444
 
436
445
  if self.color:
437
- is_exported = True
438
446
  for credential in credentials:
439
447
  for line_data in credential.line_data_list:
440
448
  # bright rule name and path or info
@@ -443,6 +451,6 @@ class CredSweeper:
443
451
  Style.RESET_ALL)
444
452
  print(line_data.get_colored_line(hashed=self.hashed, subtext=self.subtext))
445
453
 
446
- if is_exported is False:
454
+ if self.stdout:
447
455
  for credential in credentials:
448
456
  print(credential.to_str(hashed=self.hashed, subtext=self.subtext))
@@ -3,27 +3,30 @@ import re
3
3
 
4
4
  class KeywordPattern:
5
5
  """Pattern set of keyword types"""
6
- key_left = r"(\\[nrt]|%[0-9a-f]{2})?"\
7
- r"(?P<variable>(([`'\"]+[^:='\"`}<>\\/&?]*|[^:='\"`}<>\s()\\/&?;,%]*)" \
6
+ key_left = r"(\\[nrt]|%[0-9a-f]{2})?" \
7
+ r"(?P<variable>(([`'\"]{1,8}[^:='\"`}<>\\/&?]*|[^:='\"`}<>\s()\\/&?;,%]*)" \
8
8
  r"(?P<keyword>"
9
9
  # there will be inserted a keyword
10
10
  key_right = r")" \
11
- r"(&(quot|apos);|[^%:='\"`<>{?!&]*)[`'\"]*))" # <variable>
12
- separator = r"(\s|\\+[tnr])*\]?(\s|\\+[tnr])*" \
13
- r"(?P<separator>:( [a-z]{3,9}[?]? )?=|:|=(>|&gt;|\\u0026gt;)|!=|===|==|=|%3d)" \
14
- r"(\s|\\+[tnr])*"
11
+ r"[^%:='\"`<>{?!&]*" \
12
+ r")" \
13
+ r"(&(quot|apos);|%[0-9a-f]{2}|[`'\"])*" \
14
+ r")" # <variable>
15
+ separator = r"(\s|\\{1,8}[tnr])*\]?(\s|\\{1,8}[tnr])*" \
16
+ r"(?P<separator>:(\s[a-z]{3,9}[?]?\s)?=|:|=(>|&gt;|\\u0026gt;)|!==|!=|===|==|=|%3d)" \
17
+ r"(\s|\\{1,8}[tnr])*"
15
18
  # might be curly, square or parenthesis with words before
16
19
  wrap = r"(?P<wrap>(" \
17
- r"(new(\s|\\+[tnr])+)?" \
20
+ r"(new(\s|\\{1,8}[tnr]){1,8})?" \
18
21
  r"([0-9a-z_.]|-(>|(&|\\\\*u0026)gt;))*" \
19
- r"[\[\(\{]"\
20
- r"(\s|\\+[tnr])*" \
22
+ r"[\[\(\{]" \
23
+ r"(\s|\\{1,8}[tnr])*" \
21
24
  r"([0-9a-z_]{1,32}=)?" \
22
- r")+)?"
25
+ r"){1,8})?"
23
26
  string_prefix = r"(((b|r|br|rb|u|f|rf|fr|l|@)(?=(\\*[`'\"])))?"
24
27
  left_quote = r"(?P<value_leftquote>((?P<esq>\\{1,8})?([`'\"]|&(quot|apos);)){1,4}))?"
25
28
  # Authentication scheme ( oauth | basic | bearer | apikey ) precedes to credential
26
- auth_keywords = r"( ?(oauth|bot|basic|bearer|apikey|accesskey) )?"
29
+ auth_keywords = r"(\s?(oauth|bot|basic|bearer|apikey|accesskey)\s)?"
27
30
  value = r"(?P<value>" \
28
31
  r"(?(value_leftquote)" \
29
32
  r"(" \
@@ -31,11 +34,15 @@ class KeywordPattern:
31
34
  r"(?(esq)((?!(?P=esq)([`'\"]|&(quot|apos);)).)|((?!(?P=value_leftquote)).)))" \
32
35
  r"|" \
33
36
  r"(?!&(quot|apos);)" \
34
- r"(\\+([ tnr]|[^\s`'\"])|[^\s`'\",;\\])" \
35
- r"){3,8000}" \
37
+ r"(\\{1,8}([ tnr]|[^\s`'\"])" \
38
+ r"|" \
39
+ r"(?P<url_esc>%[0-9a-f]{2})" \
40
+ r"|" \
41
+ r"(?(url_esc)[^\s`'\",;\\&]|[^\s`'\",;\\])" \
42
+ r")){3,8000}" \
36
43
  r"|(\{[^}]{3,8000}\})" \
37
44
  r"|(<[^>]{3,8000}>)" \
38
- r")"
45
+ r")" # <value>
39
46
  right_quote = r"(?(value_leftquote)" \
40
47
  r"(?P<value_rightquote>(?<!\\)(?P=value_leftquote)|\\$|(?<=[0-9a-z+_/-])$)" \
41
48
  r"|" \
@@ -44,7 +51,7 @@ class KeywordPattern:
44
51
  @classmethod
45
52
  def get_keyword_pattern(cls, keyword: str) -> re.Pattern:
46
53
  """Returns compiled regex pattern"""
47
- expression = "".join([ #
54
+ expression = ''.join([ #
48
55
  cls.key_left, #
49
56
  keyword, #
50
57
  cls.key_right, #
@@ -9,16 +9,24 @@ logger = logging.getLogger(__name__)
9
9
 
10
10
 
11
11
  class CredentialManager:
12
- """The manager allows you to store, add and delete separate credit candidates.
13
-
14
- Parameters:
15
- candidates: list of credential candidates
16
-
17
- """
12
+ """The manager allows you to store, add and delete separate credit candidates."""
18
13
 
19
14
  def __init__(self) -> None:
20
15
  self.candidates: List[Candidate] = list(Manager().list())
21
16
 
17
+ def clear_credentials(self) -> None:
18
+ """Clear credential candidates stored in the manager."""
19
+ self.candidates.clear()
20
+
21
+ def len_credentials(self) -> int:
22
+ """Get number of credential candidates stored in the manager.
23
+
24
+ Return:
25
+ Non-negative integer
26
+
27
+ """
28
+ return len(self.candidates)
29
+
22
30
  def get_credentials(self) -> List[Candidate]:
23
31
  """Get all credential candidates stored in the manager.
24
32
 
@@ -8,22 +8,35 @@ from credsweeper.utils import Util
8
8
 
9
9
 
10
10
  class ValueAllowlistCheck(Filter):
11
- """Check that patterns from the list is not present in the candidate value."""
11
+ """Check that the patterns do not MATCH the candidate value."""
12
12
 
13
13
  ALLOWED = [
14
14
  r"ENC\(.*\)", #
15
15
  r"ENC\[.*\]", #
16
16
  r"\$\{(\*|[0-9]+|[a-z_].*)\}", #
17
- r"\$([0-9]+\b|[a-z_]+[0-9a-z_]*)", #
17
+ r"\$[0-9]+(\s|$)", #
18
18
  r"\$\$[a-z_]+(\^%[0-9a-z_]+)?", #
19
- r"#\{.*\}", #
19
+ r"#\{.+\}", # Ruby: String Interpolation
20
20
  r"\{\{.+\}\}", #
21
- r"\S{0,5}\*{5,}", #
22
21
  r".*@@@hl@@@(암호|비번|PW|PASS)@@@endhl@@@", #
23
22
  ]
24
23
 
25
24
  ALLOWED_PATTERN = re.compile(Util.get_regex_combine_or(ALLOWED), flags=re.IGNORECASE)
26
- ALLOWED_UNQUOTED_PATTERN = re.compile(r"[~a-z0-9_]+((\.|->)[a-z0-9_]+)+\(.*$", flags=re.IGNORECASE)
25
+
26
+ ALLOWED_QUOTED = [
27
+ r"\$[a-z_]+[0-9a-z_]*([$\s]|$)", #
28
+ r".*\*\*\*", #
29
+ ]
30
+
31
+ ALLOWED_QUOTED_PATTERN = re.compile(Util.get_regex_combine_or(ALLOWED_QUOTED), flags=re.IGNORECASE)
32
+
33
+ ALLOWED_UNQUOTED = [
34
+ r"[~a-z0-9_]+((\.|->)[a-z0-9_]+)+\(.*$", #
35
+ r"\$[a-z_]+[0-9a-z_]*\b", #
36
+ r".*\*\*\*\*\*", #
37
+ ]
38
+
39
+ ALLOWED_UNQUOTED_PATTERN = re.compile(Util.get_regex_combine_or(ALLOWED_UNQUOTED), flags=re.IGNORECASE)
27
40
 
28
41
  def __init__(self, config: Config = None) -> None:
29
42
  pass
@@ -42,8 +55,11 @@ class ValueAllowlistCheck(Filter):
42
55
 
43
56
  if self.ALLOWED_PATTERN.match(line_data.value):
44
57
  return True
45
-
46
- if not line_data.is_well_quoted_value and self.ALLOWED_UNQUOTED_PATTERN.match(line_data.value):
47
- return True
58
+ elif line_data.is_well_quoted_value:
59
+ if self.ALLOWED_QUOTED_PATTERN.match(line_data.value):
60
+ return True
61
+ else:
62
+ if self.ALLOWED_UNQUOTED_PATTERN.match(line_data.value):
63
+ return True
48
64
 
49
65
  return False
@@ -11,8 +11,11 @@ class ValueBlocklistCheck(Filter):
11
11
  "true",
12
12
  "false",
13
13
  "null",
14
+ "none",
14
15
  "bearer",
15
16
  "string",
17
+ "value",
18
+ "undefined",
16
19
  ]
17
20
 
18
21
  def __init__(self, config: Config = None) -> None:
@@ -37,10 +37,9 @@ class ValueTokenBaseCheck(Filter):
37
37
 
38
38
  @staticmethod
39
39
  def get_ppf(n: int) -> float:
40
- """
41
- from scipy.stats import t
42
- print('\n'.join(f'{n}: {t.ppf(0.9827, n-1):.8f},' for n in [8,10,15,16,20,24,25,32,40,50,64]))
43
- """
40
+ """Code used to produce the values"""
41
+ # from scipy.stats import t
42
+ # print('\n'.join(f'{n}: {t.ppf(0.9827, n-1):.8f},' for n in [8,10,15,16,20,24,25,32,40,50,64]))
44
43
  return ValueTokenBaseCheck.MUL_DICT[n]
45
44
 
46
45
  def run(self, line_data: LineData, target: AnalysisTarget) -> bool:
@@ -1391,6 +1391,22 @@
1391
1391
  - code
1392
1392
  - doc
1393
1393
 
1394
+ - name: Tavily API Key
1395
+ severity: high
1396
+ confidence: strong
1397
+ type: pattern
1398
+ values:
1399
+ - (?:(?<![0-9A-Za-z_-])|\\[0abfnrtv]|(%|\\x)[0-9A-Fa-f]{2}|\\[0-7]{3}|\\[Uu]([0-9A-Fa-f]{4}){1,2}|\x1B\[[0-9;]{0,80}m)(?P<value>tvly-[0-9A-Za-z_-]{32,40})(?![0-9A-Za-z_-])
1400
+ min_line_len: 37
1401
+ filter_type:
1402
+ - ValuePatternCheck(5)
1403
+ - ValueEntropyBase64Check
1404
+ required_substrings:
1405
+ - tvly-
1406
+ target:
1407
+ - code
1408
+ - doc
1409
+
1394
1410
  - name: Discord Bot Token
1395
1411
  severity: high
1396
1412
  confidence: strong
@@ -25,11 +25,37 @@ class HopStat:
25
25
  ')': '0',
26
26
  '_': '-',
27
27
  '+': '=',
28
+ 'Q': 'q',
29
+ 'W': 'w',
30
+ 'E': 'e',
31
+ 'R': 'r',
32
+ 'T': 't',
33
+ 'Y': 'y',
34
+ 'U': 'u',
35
+ 'I': 'i',
36
+ 'O': 'o',
37
+ 'P': 'p',
28
38
  '{': '[',
29
39
  '}': ']',
30
40
  '|': '\\',
41
+ 'A': 'a',
42
+ 'S': 's',
43
+ 'D': 'd',
44
+ 'F': 'f',
45
+ 'G': 'g',
46
+ 'H': 'h',
47
+ 'J': 'j',
48
+ 'K': 'k',
49
+ 'L': 'l',
31
50
  ':': ';',
32
51
  '"': "'",
52
+ 'Z': 'z',
53
+ 'X': 'x',
54
+ 'C': 'c',
55
+ 'V': 'v',
56
+ 'B': 'b',
57
+ 'N': 'n',
58
+ 'M': 'm',
33
59
  '<': ',',
34
60
  '>': '.',
35
61
  '?': '/',
@@ -75,7 +101,7 @@ class HopStat:
75
101
 
76
102
  """
77
103
  hops = []
78
- value = value.lower().translate(HopStat.TRANSLATION)
104
+ value = value.translate(HopStat.TRANSLATION)
79
105
  for a, b in zip(value[:-1], value[1:]):
80
106
  hop = self.__hop_dict.get((a, b))
81
107
  if hop is None:
File without changes
File without changes