souleyez 2.43.28__py3-none-any.whl → 2.43.32__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.
Files changed (356) hide show
  1. souleyez/__init__.py +1 -2
  2. souleyez/ai/__init__.py +21 -15
  3. souleyez/ai/action_mapper.py +249 -150
  4. souleyez/ai/chain_advisor.py +116 -100
  5. souleyez/ai/claude_provider.py +29 -28
  6. souleyez/ai/context_builder.py +80 -62
  7. souleyez/ai/executor.py +158 -117
  8. souleyez/ai/feedback_handler.py +136 -121
  9. souleyez/ai/llm_factory.py +27 -20
  10. souleyez/ai/llm_provider.py +4 -2
  11. souleyez/ai/ollama_provider.py +6 -9
  12. souleyez/ai/ollama_service.py +44 -37
  13. souleyez/ai/path_scorer.py +91 -76
  14. souleyez/ai/recommender.py +176 -144
  15. souleyez/ai/report_context.py +74 -73
  16. souleyez/ai/report_service.py +84 -66
  17. souleyez/ai/result_parser.py +222 -229
  18. souleyez/ai/safety.py +67 -44
  19. souleyez/auth/__init__.py +23 -22
  20. souleyez/auth/audit.py +36 -26
  21. souleyez/auth/engagement_access.py +65 -48
  22. souleyez/auth/permissions.py +14 -3
  23. souleyez/auth/session_manager.py +54 -37
  24. souleyez/auth/user_manager.py +109 -64
  25. souleyez/commands/audit.py +40 -43
  26. souleyez/commands/auth.py +35 -15
  27. souleyez/commands/deliverables.py +55 -50
  28. souleyez/commands/engagement.py +47 -28
  29. souleyez/commands/license.py +32 -23
  30. souleyez/commands/screenshots.py +36 -32
  31. souleyez/commands/user.py +82 -36
  32. souleyez/config.py +52 -44
  33. souleyez/core/credential_tester.py +87 -81
  34. souleyez/core/cve_mappings.py +179 -192
  35. souleyez/core/cve_matcher.py +162 -148
  36. souleyez/core/msf_auto_mapper.py +100 -83
  37. souleyez/core/msf_chain_engine.py +294 -256
  38. souleyez/core/msf_database.py +153 -70
  39. souleyez/core/msf_integration.py +679 -673
  40. souleyez/core/msf_rpc_client.py +40 -42
  41. souleyez/core/msf_rpc_manager.py +77 -79
  42. souleyez/core/msf_sync_manager.py +241 -181
  43. souleyez/core/network_utils.py +22 -15
  44. souleyez/core/parser_handler.py +34 -25
  45. souleyez/core/pending_chains.py +114 -63
  46. souleyez/core/templates.py +158 -107
  47. souleyez/core/tool_chaining.py +9592 -2879
  48. souleyez/core/version_utils.py +79 -94
  49. souleyez/core/vuln_correlation.py +136 -89
  50. souleyez/core/web_utils.py +33 -32
  51. souleyez/data/wordlists/ad_users.txt +378 -0
  52. souleyez/data/wordlists/api_endpoints_large.txt +769 -0
  53. souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
  54. souleyez/data/wordlists/lfi_payloads.txt +82 -0
  55. souleyez/data/wordlists/passwords_brute.txt +1548 -0
  56. souleyez/data/wordlists/passwords_crack.txt +2479 -0
  57. souleyez/data/wordlists/passwords_spray.txt +386 -0
  58. souleyez/data/wordlists/subdomains_large.txt +5057 -0
  59. souleyez/data/wordlists/usernames_common.txt +694 -0
  60. souleyez/data/wordlists/web_dirs_large.txt +4769 -0
  61. souleyez/detection/__init__.py +1 -1
  62. souleyez/detection/attack_signatures.py +12 -17
  63. souleyez/detection/mitre_mappings.py +61 -55
  64. souleyez/detection/validator.py +97 -86
  65. souleyez/devtools.py +23 -10
  66. souleyez/docs/README.md +4 -4
  67. souleyez/docs/api-reference/cli-commands.md +2 -2
  68. souleyez/docs/developer-guide/adding-new-tools.md +562 -0
  69. souleyez/docs/user-guide/auto-chaining.md +30 -8
  70. souleyez/docs/user-guide/getting-started.md +1 -1
  71. souleyez/docs/user-guide/installation.md +26 -3
  72. souleyez/docs/user-guide/metasploit-integration.md +2 -2
  73. souleyez/docs/user-guide/rbac.md +1 -1
  74. souleyez/docs/user-guide/scope-management.md +1 -1
  75. souleyez/docs/user-guide/siem-integration.md +1 -1
  76. souleyez/docs/user-guide/tools-reference.md +1 -8
  77. souleyez/docs/user-guide/worker-management.md +1 -1
  78. souleyez/engine/background.py +1238 -535
  79. souleyez/engine/base.py +4 -1
  80. souleyez/engine/job_status.py +17 -49
  81. souleyez/engine/log_sanitizer.py +103 -77
  82. souleyez/engine/manager.py +38 -7
  83. souleyez/engine/result_handler.py +2198 -1550
  84. souleyez/engine/worker_manager.py +50 -41
  85. souleyez/export/evidence_bundle.py +72 -62
  86. souleyez/feature_flags/features.py +16 -20
  87. souleyez/feature_flags.py +5 -9
  88. souleyez/handlers/__init__.py +11 -0
  89. souleyez/handlers/base.py +188 -0
  90. souleyez/handlers/bash_handler.py +277 -0
  91. souleyez/handlers/bloodhound_handler.py +243 -0
  92. souleyez/handlers/certipy_handler.py +311 -0
  93. souleyez/handlers/crackmapexec_handler.py +486 -0
  94. souleyez/handlers/dnsrecon_handler.py +344 -0
  95. souleyez/handlers/enum4linux_handler.py +400 -0
  96. souleyez/handlers/evil_winrm_handler.py +493 -0
  97. souleyez/handlers/ffuf_handler.py +815 -0
  98. souleyez/handlers/gobuster_handler.py +1114 -0
  99. souleyez/handlers/gpp_extract_handler.py +334 -0
  100. souleyez/handlers/hashcat_handler.py +444 -0
  101. souleyez/handlers/hydra_handler.py +563 -0
  102. souleyez/handlers/impacket_getuserspns_handler.py +343 -0
  103. souleyez/handlers/impacket_psexec_handler.py +222 -0
  104. souleyez/handlers/impacket_secretsdump_handler.py +426 -0
  105. souleyez/handlers/john_handler.py +286 -0
  106. souleyez/handlers/katana_handler.py +425 -0
  107. souleyez/handlers/kerbrute_handler.py +298 -0
  108. souleyez/handlers/ldapsearch_handler.py +636 -0
  109. souleyez/handlers/lfi_extract_handler.py +464 -0
  110. souleyez/handlers/msf_auxiliary_handler.py +408 -0
  111. souleyez/handlers/msf_exploit_handler.py +380 -0
  112. souleyez/handlers/nikto_handler.py +413 -0
  113. souleyez/handlers/nmap_handler.py +821 -0
  114. souleyez/handlers/nuclei_handler.py +359 -0
  115. souleyez/handlers/nxc_handler.py +371 -0
  116. souleyez/handlers/rdp_sec_check_handler.py +353 -0
  117. souleyez/handlers/registry.py +288 -0
  118. souleyez/handlers/responder_handler.py +232 -0
  119. souleyez/handlers/service_explorer_handler.py +434 -0
  120. souleyez/handlers/smbclient_handler.py +344 -0
  121. souleyez/handlers/smbmap_handler.py +510 -0
  122. souleyez/handlers/smbpasswd_handler.py +296 -0
  123. souleyez/handlers/sqlmap_handler.py +1116 -0
  124. souleyez/handlers/theharvester_handler.py +601 -0
  125. souleyez/handlers/whois_handler.py +277 -0
  126. souleyez/handlers/wpscan_handler.py +554 -0
  127. souleyez/history.py +32 -16
  128. souleyez/importers/msf_importer.py +106 -75
  129. souleyez/importers/smart_importer.py +208 -147
  130. souleyez/integrations/siem/__init__.py +10 -10
  131. souleyez/integrations/siem/base.py +17 -18
  132. souleyez/integrations/siem/elastic.py +108 -122
  133. souleyez/integrations/siem/factory.py +207 -80
  134. souleyez/integrations/siem/googlesecops.py +146 -154
  135. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  136. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  137. souleyez/integrations/siem/sentinel.py +107 -109
  138. souleyez/integrations/siem/splunk.py +246 -212
  139. souleyez/integrations/siem/wazuh.py +65 -71
  140. souleyez/integrations/wazuh/__init__.py +5 -5
  141. souleyez/integrations/wazuh/client.py +70 -93
  142. souleyez/integrations/wazuh/config.py +85 -57
  143. souleyez/integrations/wazuh/host_mapper.py +28 -36
  144. souleyez/integrations/wazuh/sync.py +78 -68
  145. souleyez/intelligence/__init__.py +4 -5
  146. souleyez/intelligence/correlation_analyzer.py +309 -295
  147. souleyez/intelligence/exploit_knowledge.py +661 -623
  148. souleyez/intelligence/exploit_suggestions.py +159 -139
  149. souleyez/intelligence/gap_analyzer.py +132 -97
  150. souleyez/intelligence/gap_detector.py +251 -214
  151. souleyez/intelligence/sensitive_tables.py +266 -129
  152. souleyez/intelligence/service_parser.py +137 -123
  153. souleyez/intelligence/surface_analyzer.py +407 -268
  154. souleyez/intelligence/target_parser.py +159 -162
  155. souleyez/licensing/__init__.py +6 -6
  156. souleyez/licensing/validator.py +17 -19
  157. souleyez/log_config.py +79 -54
  158. souleyez/main.py +1505 -687
  159. souleyez/migrations/fix_job_counter.py +16 -14
  160. souleyez/parsers/bloodhound_parser.py +41 -39
  161. souleyez/parsers/crackmapexec_parser.py +178 -111
  162. souleyez/parsers/dalfox_parser.py +72 -77
  163. souleyez/parsers/dnsrecon_parser.py +103 -91
  164. souleyez/parsers/enum4linux_parser.py +183 -153
  165. souleyez/parsers/ffuf_parser.py +29 -25
  166. souleyez/parsers/gobuster_parser.py +301 -41
  167. souleyez/parsers/hashcat_parser.py +324 -79
  168. souleyez/parsers/http_fingerprint_parser.py +350 -103
  169. souleyez/parsers/hydra_parser.py +131 -111
  170. souleyez/parsers/impacket_parser.py +231 -178
  171. souleyez/parsers/john_parser.py +98 -86
  172. souleyez/parsers/katana_parser.py +316 -0
  173. souleyez/parsers/msf_parser.py +943 -498
  174. souleyez/parsers/nikto_parser.py +346 -65
  175. souleyez/parsers/nmap_parser.py +262 -174
  176. souleyez/parsers/nuclei_parser.py +40 -44
  177. souleyez/parsers/responder_parser.py +26 -26
  178. souleyez/parsers/searchsploit_parser.py +74 -74
  179. souleyez/parsers/service_explorer_parser.py +279 -0
  180. souleyez/parsers/smbmap_parser.py +180 -124
  181. souleyez/parsers/sqlmap_parser.py +434 -308
  182. souleyez/parsers/theharvester_parser.py +75 -57
  183. souleyez/parsers/whois_parser.py +135 -94
  184. souleyez/parsers/wpscan_parser.py +278 -190
  185. souleyez/plugins/afp.py +44 -36
  186. souleyez/plugins/afp_brute.py +114 -46
  187. souleyez/plugins/ard.py +48 -37
  188. souleyez/plugins/bloodhound.py +95 -61
  189. souleyez/plugins/certipy.py +303 -0
  190. souleyez/plugins/crackmapexec.py +186 -85
  191. souleyez/plugins/dalfox.py +120 -59
  192. souleyez/plugins/dns_hijack.py +146 -41
  193. souleyez/plugins/dnsrecon.py +97 -61
  194. souleyez/plugins/enum4linux.py +91 -66
  195. souleyez/plugins/evil_winrm.py +291 -0
  196. souleyez/plugins/ffuf.py +166 -90
  197. souleyez/plugins/firmware_extract.py +133 -29
  198. souleyez/plugins/gobuster.py +387 -190
  199. souleyez/plugins/gpp_extract.py +393 -0
  200. souleyez/plugins/hashcat.py +100 -73
  201. souleyez/plugins/http_fingerprint.py +854 -267
  202. souleyez/plugins/hydra.py +566 -200
  203. souleyez/plugins/impacket_getnpusers.py +117 -69
  204. souleyez/plugins/impacket_psexec.py +84 -64
  205. souleyez/plugins/impacket_secretsdump.py +103 -69
  206. souleyez/plugins/impacket_smbclient.py +89 -75
  207. souleyez/plugins/john.py +86 -69
  208. souleyez/plugins/katana.py +313 -0
  209. souleyez/plugins/kerbrute.py +237 -0
  210. souleyez/plugins/lfi_extract.py +541 -0
  211. souleyez/plugins/macos_ssh.py +117 -48
  212. souleyez/plugins/mdns.py +35 -30
  213. souleyez/plugins/msf_auxiliary.py +253 -130
  214. souleyez/plugins/msf_exploit.py +239 -161
  215. souleyez/plugins/nikto.py +134 -78
  216. souleyez/plugins/nmap.py +275 -91
  217. souleyez/plugins/nuclei.py +180 -89
  218. souleyez/plugins/nxc.py +285 -0
  219. souleyez/plugins/plugin_base.py +35 -36
  220. souleyez/plugins/plugin_template.py +13 -5
  221. souleyez/plugins/rdp_sec_check.py +130 -0
  222. souleyez/plugins/responder.py +112 -71
  223. souleyez/plugins/router_http_brute.py +76 -65
  224. souleyez/plugins/router_ssh_brute.py +118 -41
  225. souleyez/plugins/router_telnet_brute.py +124 -42
  226. souleyez/plugins/routersploit.py +91 -59
  227. souleyez/plugins/routersploit_exploit.py +77 -55
  228. souleyez/plugins/searchsploit.py +91 -77
  229. souleyez/plugins/service_explorer.py +1160 -0
  230. souleyez/plugins/smbmap.py +122 -72
  231. souleyez/plugins/smbpasswd.py +215 -0
  232. souleyez/plugins/sqlmap.py +301 -113
  233. souleyez/plugins/theharvester.py +127 -75
  234. souleyez/plugins/tr069.py +79 -57
  235. souleyez/plugins/upnp.py +65 -47
  236. souleyez/plugins/upnp_abuse.py +73 -55
  237. souleyez/plugins/vnc_access.py +129 -42
  238. souleyez/plugins/vnc_brute.py +109 -38
  239. souleyez/plugins/whois.py +77 -58
  240. souleyez/plugins/wpscan.py +173 -69
  241. souleyez/reporting/__init__.py +2 -1
  242. souleyez/reporting/attack_chain.py +411 -346
  243. souleyez/reporting/charts.py +436 -501
  244. souleyez/reporting/compliance_mappings.py +334 -201
  245. souleyez/reporting/detection_report.py +126 -125
  246. souleyez/reporting/formatters.py +828 -591
  247. souleyez/reporting/generator.py +386 -302
  248. souleyez/reporting/metrics.py +72 -75
  249. souleyez/scanner.py +35 -29
  250. souleyez/security/__init__.py +37 -11
  251. souleyez/security/scope_validator.py +175 -106
  252. souleyez/security/validation.py +223 -149
  253. souleyez/security.py +22 -6
  254. souleyez/storage/credentials.py +247 -186
  255. souleyez/storage/crypto.py +296 -129
  256. souleyez/storage/database.py +73 -50
  257. souleyez/storage/db.py +58 -36
  258. souleyez/storage/deliverable_evidence.py +177 -128
  259. souleyez/storage/deliverable_exporter.py +282 -246
  260. souleyez/storage/deliverable_templates.py +134 -116
  261. souleyez/storage/deliverables.py +135 -130
  262. souleyez/storage/engagements.py +109 -56
  263. souleyez/storage/evidence.py +181 -152
  264. souleyez/storage/execution_log.py +31 -17
  265. souleyez/storage/exploit_attempts.py +93 -57
  266. souleyez/storage/exploits.py +67 -36
  267. souleyez/storage/findings.py +48 -61
  268. souleyez/storage/hosts.py +176 -144
  269. souleyez/storage/migrate_to_engagements.py +43 -19
  270. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  271. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  272. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  273. souleyez/storage/migrations/_005_screenshots.py +13 -5
  274. souleyez/storage/migrations/_006_deliverables.py +13 -5
  275. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  276. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  277. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  278. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  279. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  280. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  281. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  282. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  283. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  284. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  285. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  286. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  287. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  288. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  289. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  290. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  291. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  292. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  293. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  294. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  295. souleyez/storage/migrations/__init__.py +26 -26
  296. souleyez/storage/migrations/migration_manager.py +19 -19
  297. souleyez/storage/msf_sessions.py +100 -65
  298. souleyez/storage/osint.py +17 -24
  299. souleyez/storage/recommendation_engine.py +269 -235
  300. souleyez/storage/screenshots.py +33 -32
  301. souleyez/storage/smb_shares.py +136 -92
  302. souleyez/storage/sqlmap_data.py +183 -128
  303. souleyez/storage/team_collaboration.py +135 -141
  304. souleyez/storage/timeline_tracker.py +122 -94
  305. souleyez/storage/wazuh_vulns.py +64 -66
  306. souleyez/storage/web_paths.py +33 -37
  307. souleyez/testing/credential_tester.py +221 -205
  308. souleyez/ui/__init__.py +1 -1
  309. souleyez/ui/ai_quotes.py +12 -12
  310. souleyez/ui/attack_surface.py +2439 -1516
  311. souleyez/ui/chain_rules_view.py +914 -382
  312. souleyez/ui/correlation_view.py +312 -230
  313. souleyez/ui/dashboard.py +2382 -1130
  314. souleyez/ui/deliverables_view.py +148 -62
  315. souleyez/ui/design_system.py +13 -13
  316. souleyez/ui/errors.py +49 -49
  317. souleyez/ui/evidence_linking_view.py +284 -179
  318. souleyez/ui/evidence_vault.py +393 -285
  319. souleyez/ui/exploit_suggestions_view.py +555 -349
  320. souleyez/ui/export_view.py +100 -66
  321. souleyez/ui/gap_analysis_view.py +315 -171
  322. souleyez/ui/help_system.py +105 -97
  323. souleyez/ui/intelligence_view.py +436 -293
  324. souleyez/ui/interactive.py +23142 -10430
  325. souleyez/ui/interactive_selector.py +75 -68
  326. souleyez/ui/log_formatter.py +47 -39
  327. souleyez/ui/menu_components.py +22 -13
  328. souleyez/ui/msf_auxiliary_menu.py +184 -133
  329. souleyez/ui/pending_chains_view.py +336 -172
  330. souleyez/ui/progress_indicators.py +5 -3
  331. souleyez/ui/recommendations_view.py +195 -137
  332. souleyez/ui/rule_builder.py +343 -225
  333. souleyez/ui/setup_wizard.py +678 -284
  334. souleyez/ui/shortcuts.py +217 -165
  335. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  336. souleyez/ui/splunk_vulns_view.py +139 -86
  337. souleyez/ui/team_dashboard.py +498 -335
  338. souleyez/ui/template_selector.py +196 -105
  339. souleyez/ui/terminal.py +6 -6
  340. souleyez/ui/timeline_view.py +198 -127
  341. souleyez/ui/tool_setup.py +264 -164
  342. souleyez/ui/tutorial.py +202 -72
  343. souleyez/ui/tutorial_state.py +40 -40
  344. souleyez/ui/wazuh_vulns_view.py +235 -141
  345. souleyez/ui/wordlist_browser.py +260 -107
  346. souleyez/ui.py +464 -312
  347. souleyez/utils/tool_checker.py +427 -367
  348. souleyez/utils.py +33 -29
  349. souleyez/wordlists.py +134 -167
  350. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/METADATA +1 -1
  351. souleyez-2.43.32.dist-info/RECORD +441 -0
  352. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/WHEEL +1 -1
  353. souleyez-2.43.28.dist-info/RECORD +0 -379
  354. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/entry_points.txt +0 -0
  355. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/licenses/LICENSE +0 -0
  356. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/top_level.txt +0 -0
@@ -10,41 +10,41 @@ from typing import Dict, List, Tuple, Optional
10
10
  # Do NOT skip application databases even if they seem like "test" or "lab" databases
11
11
  # Real engagements may have legitimately named databases like these
12
12
  SYSTEM_DATABASES = {
13
- 'information_schema', # MySQL metadata - no user data
14
- 'mysql', # MySQL system tables - no user data
15
- 'performance_schema', # MySQL performance metrics - no user data
16
- 'sys', # MySQL system views - no user data
13
+ "information_schema", # MySQL metadata - no user data
14
+ "mysql", # MySQL system tables - no user data
15
+ "performance_schema", # MySQL performance metrics - no user data
16
+ "sys", # MySQL system views - no user data
17
17
  }
18
18
 
19
19
  # System table patterns to skip (even in application databases)
20
20
  SYSTEM_TABLE_PATTERNS = [
21
- 'USER_PRIVILEGES',
22
- 'SCHEMA_PRIVILEGES',
23
- 'TABLE_PRIVILEGES',
24
- 'COLUMN_PRIVILEGES',
25
- 'REFERENTIAL_CONSTRAINTS',
26
- 'KEY_COLUMN_USAGE',
27
- 'TABLE_CONSTRAINTS',
28
- 'STATISTICS',
29
- 'VIEWS',
30
- 'TRIGGERS',
31
- 'ROUTINES',
32
- 'EVENTS',
33
- 'PARAMETERS',
21
+ "USER_PRIVILEGES",
22
+ "SCHEMA_PRIVILEGES",
23
+ "TABLE_PRIVILEGES",
24
+ "COLUMN_PRIVILEGES",
25
+ "REFERENTIAL_CONSTRAINTS",
26
+ "KEY_COLUMN_USAGE",
27
+ "TABLE_CONSTRAINTS",
28
+ "STATISTICS",
29
+ "VIEWS",
30
+ "TRIGGERS",
31
+ "ROUTINES",
32
+ "EVENTS",
33
+ "PARAMETERS",
34
34
  ]
35
35
 
36
36
  # Skip tables with these suffixes (logs, history, metadata)
37
37
  SKIP_TABLE_SUFFIXES = [
38
- '_log',
39
- '_logs',
40
- '_history',
41
- '_audit',
42
- '_backup',
43
- '_temp',
44
- '_tmp',
45
- '_cache',
46
- '_meta',
47
- '_metadata'
38
+ "_log",
39
+ "_logs",
40
+ "_history",
41
+ "_audit",
42
+ "_backup",
43
+ "_temp",
44
+ "_tmp",
45
+ "_cache",
46
+ "_meta",
47
+ "_metadata",
48
48
  ]
49
49
 
50
50
 
@@ -59,69 +59,143 @@ def is_system_table(table_name: str) -> bool:
59
59
  """Check if table is a system table (should skip)."""
60
60
  if not table_name:
61
61
  return False
62
-
62
+
63
63
  table_lower = table_name.lower().strip()
64
-
64
+
65
65
  # Check against system table patterns
66
66
  for pattern in SYSTEM_TABLE_PATTERNS:
67
67
  if pattern.lower() in table_lower:
68
68
  return True
69
-
69
+
70
70
  # Check suffixes
71
71
  for suffix in SKIP_TABLE_SUFFIXES:
72
72
  if table_lower.endswith(suffix):
73
73
  return True
74
-
74
+
75
75
  return False
76
76
 
77
77
 
78
78
  # Sensitive table name patterns by category
79
79
  SENSITIVE_TABLE_PATTERNS = {
80
- 'credentials': [
81
- 'users', 'user', 'accounts', 'account', 'members', 'member',
82
- 'logins', 'login', 'auth', 'authentication',
83
- 'customers', 'customer', 'clients', 'client',
84
- 'administrators', 'admin', 'admins', 'staff', 'employees', 'employee'
80
+ "credentials": [
81
+ "users",
82
+ "user",
83
+ "accounts",
84
+ "account",
85
+ "members",
86
+ "member",
87
+ "logins",
88
+ "login",
89
+ "auth",
90
+ "authentication",
91
+ "customers",
92
+ "customer",
93
+ "clients",
94
+ "client",
95
+ "administrators",
96
+ "admin",
97
+ "admins",
98
+ "staff",
99
+ "employees",
100
+ "employee",
85
101
  ],
86
- 'payment': [
87
- 'credit_cards', 'creditcards', 'cards', 'card',
88
- 'payments', 'payment', 'transactions', 'transaction',
89
- 'billing', 'invoices', 'invoice', 'orders', 'order'
102
+ "payment": [
103
+ "credit_cards",
104
+ "creditcards",
105
+ "cards",
106
+ "card",
107
+ "payments",
108
+ "payment",
109
+ "transactions",
110
+ "transaction",
111
+ "billing",
112
+ "invoices",
113
+ "invoice",
114
+ "orders",
115
+ "order",
90
116
  ],
91
- 'sensitive_pii': [
92
- 'profiles', 'profile', 'persons', 'person',
93
- 'contacts', 'contact', 'addresses', 'address',
94
- 'personal_info', 'pii', 'identities', 'identity',
95
- 'social_security', 'ssn', 'drivers_license', 'passport'
117
+ "sensitive_pii": [
118
+ "profiles",
119
+ "profile",
120
+ "persons",
121
+ "person",
122
+ "contacts",
123
+ "contact",
124
+ "addresses",
125
+ "address",
126
+ "personal_info",
127
+ "pii",
128
+ "identities",
129
+ "identity",
130
+ "social_security",
131
+ "ssn",
132
+ "drivers_license",
133
+ "passport",
134
+ ],
135
+ "secrets": [
136
+ "api_keys",
137
+ "tokens",
138
+ "secrets",
139
+ "keys",
140
+ "passwords",
141
+ "password",
142
+ "credentials",
143
+ "creds",
144
+ "sessions",
145
+ "session",
146
+ "oauth",
147
+ "jwt",
96
148
  ],
97
- 'secrets': [
98
- 'api_keys', 'tokens', 'secrets', 'keys',
99
- 'passwords', 'password', 'credentials', 'creds',
100
- 'sessions', 'session', 'oauth', 'jwt'
101
- ]
102
149
  }
103
150
 
104
151
  # Column name patterns for validation
105
152
  SENSITIVE_COLUMN_PATTERNS = {
106
- 'credentials': [
107
- 'password', 'passwd', 'pass', 'pwd', 'hash',
108
- 'username', 'user', 'email', 'login',
109
- 'salt', 'token', 'secret', 'api_key'
153
+ "credentials": [
154
+ "password",
155
+ "passwd",
156
+ "pass",
157
+ "pwd",
158
+ "hash",
159
+ "username",
160
+ "user",
161
+ "email",
162
+ "login",
163
+ "salt",
164
+ "token",
165
+ "secret",
166
+ "api_key",
167
+ ],
168
+ "payment": [
169
+ "card_number",
170
+ "cvv",
171
+ "expiry",
172
+ "card_type",
173
+ "account_number",
174
+ "routing_number",
175
+ "iban",
176
+ "swift",
177
+ "cardholder",
178
+ "billing",
110
179
  ],
111
- 'payment': [
112
- 'card_number', 'cvv', 'expiry', 'card_type',
113
- 'account_number', 'routing_number', 'iban', 'swift',
114
- 'cardholder', 'billing'
180
+ "pii": [
181
+ "ssn",
182
+ "social_security",
183
+ "tax_id",
184
+ "national_id",
185
+ "address",
186
+ "phone",
187
+ "dob",
188
+ "birth_date",
189
+ "drivers_license",
190
+ "passport",
191
+ "maiden_name",
115
192
  ],
116
- 'pii': [
117
- 'ssn', 'social_security', 'tax_id', 'national_id',
118
- 'address', 'phone', 'dob', 'birth_date',
119
- 'drivers_license', 'passport', 'maiden_name'
120
- ]
121
193
  }
122
194
 
123
195
 
124
- def is_sensitive_table(table_name: str, category: Optional[str] = None) -> Tuple[bool, Optional[str], int]:
196
+ def is_sensitive_table(
197
+ table_name: str, category: Optional[str] = None
198
+ ) -> Tuple[bool, Optional[str], int]:
125
199
  """
126
200
  Determine if a table name is sensitive.
127
201
 
@@ -152,17 +226,17 @@ def is_sensitive_table(table_name: str, category: Optional[str] = None) -> Tuple
152
226
  table_lower = table_name.lower().strip()
153
227
 
154
228
  # Remove common prefixes (including tiki_, drupal_, etc.)
155
- for prefix in ['tbl_', 'app_', 'wp_', 'db_', 'sys_', 'tiki_', 'drupal_', 'joomla_']:
229
+ for prefix in ["tbl_", "app_", "wp_", "db_", "sys_", "tiki_", "drupal_", "joomla_"]:
156
230
  if table_lower.startswith(prefix):
157
- table_lower = table_lower[len(prefix):]
231
+ table_lower = table_lower[len(prefix) :]
158
232
  break
159
233
 
160
234
  # Priority by category (credentials most important)
161
235
  category_priorities = {
162
- 'credentials': 10,
163
- 'payment': 9,
164
- 'secrets': 8,
165
- 'sensitive_pii': 7
236
+ "credentials": 10,
237
+ "payment": 9,
238
+ "secrets": 8,
239
+ "sensitive_pii": 7,
166
240
  }
167
241
 
168
242
  # Check against patterns
@@ -186,15 +260,19 @@ def is_sensitive_table(table_name: str, category: Optional[str] = None) -> Tuple
186
260
  return (True, cat, priority)
187
261
 
188
262
  # 2. Table ENDS with the pattern (e.g., "users_users" ends with "users")
189
- if table_lower.endswith('_' + pattern_lower) or table_lower.endswith(pattern_lower):
263
+ if table_lower.endswith("_" + pattern_lower) or table_lower.endswith(
264
+ pattern_lower
265
+ ):
190
266
  # Make sure it's a word boundary, not partial (e.g., "xusers" shouldn't match)
191
- if table_lower == pattern_lower or table_lower.endswith('_' + pattern_lower):
267
+ if table_lower == pattern_lower or table_lower.endswith(
268
+ "_" + pattern_lower
269
+ ):
192
270
  priority = category_priorities.get(cat, 5)
193
271
  return (True, cat, priority)
194
272
 
195
273
  # 3. Singular/plural variants at end only
196
- pattern_singular = pattern_lower.rstrip('s')
197
- table_singular = table_lower.rstrip('s')
274
+ pattern_singular = pattern_lower.rstrip("s")
275
+ table_singular = table_lower.rstrip("s")
198
276
  if table_singular == pattern_singular:
199
277
  priority = category_priorities.get(cat, 5)
200
278
  return (True, cat, priority)
@@ -224,22 +302,24 @@ def validate_sensitive_columns(columns: List[str], expected_category: str) -> bo
224
302
  """
225
303
  if not columns:
226
304
  return False
227
-
305
+
228
306
  # Map category to column patterns
229
307
  category_map = {
230
- 'credentials': SENSITIVE_COLUMN_PATTERNS['credentials'],
231
- 'payment': SENSITIVE_COLUMN_PATTERNS['payment'],
232
- 'sensitive_pii': SENSITIVE_COLUMN_PATTERNS['pii'],
233
- 'secrets': SENSITIVE_COLUMN_PATTERNS['credentials'] # Secrets use same patterns as credentials
308
+ "credentials": SENSITIVE_COLUMN_PATTERNS["credentials"],
309
+ "payment": SENSITIVE_COLUMN_PATTERNS["payment"],
310
+ "sensitive_pii": SENSITIVE_COLUMN_PATTERNS["pii"],
311
+ "secrets": SENSITIVE_COLUMN_PATTERNS[
312
+ "credentials"
313
+ ], # Secrets use same patterns as credentials
234
314
  }
235
-
315
+
236
316
  expected_patterns = category_map.get(expected_category, [])
237
317
  if not expected_patterns:
238
318
  return True # If no patterns defined, assume valid
239
-
319
+
240
320
  # Normalize column names
241
321
  columns_lower = [col.lower() for col in columns]
242
-
322
+
243
323
  # Check if any expected patterns match
244
324
  matches = 0
245
325
  for pattern in expected_patterns:
@@ -248,14 +328,15 @@ def validate_sensitive_columns(columns: List[str], expected_category: str) -> bo
248
328
  if pattern_lower in col or col in pattern_lower:
249
329
  matches += 1
250
330
  break
251
-
331
+
252
332
  # Require at least 2 matching columns for high confidence
253
333
  # (e.g., username + password, card_number + cvv)
254
334
  return matches >= 2
255
335
 
256
336
 
257
- def prioritize_tables(tables: Dict[str, List[str]],
258
- columns: Optional[Dict[str, List[str]]] = None) -> List[Dict]:
337
+ def prioritize_tables(
338
+ tables: Dict[str, List[str]], columns: Optional[Dict[str, List[str]]] = None
339
+ ) -> List[Dict]:
259
340
  """
260
341
  Prioritize sensitive tables for dumping.
261
342
 
@@ -281,69 +362,95 @@ def prioritize_tables(tables: Dict[str, List[str]],
281
362
  - Priority 8-10 only (avoid dumping low-confidence matches)
282
363
  """
283
364
  sensitive_tables = []
284
-
365
+
285
366
  for database, table_list in tables.items():
286
367
  for table in table_list:
287
368
  # Check if table is sensitive
288
369
  is_sensitive, category, priority = is_sensitive_table(table)
289
-
370
+
290
371
  if not is_sensitive or priority < 5:
291
372
  continue # Skip non-sensitive tables (lowered threshold for thoroughness)
292
-
373
+
293
374
  # Get columns for validation if available
294
375
  table_key = f"{database}.{table}"
295
376
  table_columns = columns.get(table_key, []) if columns else []
296
-
377
+
297
378
  # Validate columns if available (but don't skip - just note it)
298
379
  if table_columns:
299
380
  if not validate_sensitive_columns(table_columns, category):
300
381
  # Columns don't match expected pattern - reduce priority slightly
301
382
  # but still include for thoroughness
302
383
  priority -= 1
303
-
304
- sensitive_tables.append({
305
- 'database': database,
306
- 'table': table,
307
- 'category': category,
308
- 'priority': priority,
309
- 'columns': table_columns
310
- })
311
-
384
+
385
+ sensitive_tables.append(
386
+ {
387
+ "database": database,
388
+ "table": table,
389
+ "category": category,
390
+ "priority": priority,
391
+ "columns": table_columns,
392
+ }
393
+ )
394
+
312
395
  # Sort by priority (highest first), then by category importance
313
- category_order = {'credentials': 0, 'payment': 1, 'secrets': 2, 'sensitive_pii': 3}
396
+ category_order = {"credentials": 0, "payment": 1, "secrets": 2, "sensitive_pii": 3}
314
397
  sensitive_tables.sort(
315
- key=lambda t: (-t['priority'], category_order.get(t['category'], 9))
398
+ key=lambda t: (-t["priority"], category_order.get(t["category"], 9))
316
399
  )
317
-
400
+
318
401
  # Limit to top 25 tables (increased for thoroughness in real engagements)
319
402
  return sensitive_tables[:25]
320
403
 
321
404
 
322
405
  # Sensitive table names (for quick lookup without column validation)
323
406
  SENSITIVE_TABLE_NAMES = {
324
- 'users', 'user', 'accounts', 'account', 'members', 'member',
325
- 'customers', 'customer', 'clients', 'client',
326
- 'admins', 'admin', 'administrators',
327
- 'credentials', 'creds', 'passwords', 'passwd',
328
- 'logins', 'login', 'auth', 'authentication',
329
- 'sessions', 'tokens', 'api_keys', 'apikeys',
330
- 'credit_cards', 'creditcards', 'cards', 'payments',
331
- 'orders', 'transactions', 'billing',
407
+ "users",
408
+ "user",
409
+ "accounts",
410
+ "account",
411
+ "members",
412
+ "member",
413
+ "customers",
414
+ "customer",
415
+ "clients",
416
+ "client",
417
+ "admins",
418
+ "admin",
419
+ "administrators",
420
+ "credentials",
421
+ "creds",
422
+ "passwords",
423
+ "passwd",
424
+ "logins",
425
+ "login",
426
+ "auth",
427
+ "authentication",
428
+ "sessions",
429
+ "tokens",
430
+ "api_keys",
431
+ "apikeys",
432
+ "credit_cards",
433
+ "creditcards",
434
+ "cards",
435
+ "payments",
436
+ "orders",
437
+ "transactions",
438
+ "billing",
332
439
  }
333
440
 
334
441
 
335
442
  def is_sensitive_table_name(table_name: str) -> bool:
336
443
  """
337
444
  Check if table name suggests sensitive data (name-based only).
338
-
445
+
339
446
  Used for quick decisions without column information.
340
-
447
+
341
448
  Args:
342
449
  table_name: Name of the table to check
343
-
450
+
344
451
  Returns:
345
452
  bool: True if table name suggests sensitive data
346
-
453
+
347
454
  Examples:
348
455
  >>> is_sensitive_table_name('users')
349
456
  True
@@ -357,27 +464,57 @@ def is_sensitive_table_name(table_name: str) -> bool:
357
464
 
358
465
  # Sensitive column patterns (expanded for detection)
359
466
  SENSITIVE_COLUMN_KEYWORDS = {
360
- 'password', 'passwd', 'pass', 'pwd', 'secret',
361
- 'email', 'mail', 'phone', 'mobile', 'cell',
362
- 'ssn', 'social_security', 'national_id', 'tax_id',
363
- 'credit_card', 'cc_number', 'card_number', 'cvv', 'ccv',
364
- 'token', 'api_key', 'apikey', 'auth_token', 'session',
365
- 'address', 'street', 'city', 'zip', 'postal',
366
- 'dob', 'date_of_birth', 'birthday', 'birthdate',
367
- 'salary', 'income', 'bank', 'account_number', 'routing',
467
+ "password",
468
+ "passwd",
469
+ "pass",
470
+ "pwd",
471
+ "secret",
472
+ "email",
473
+ "mail",
474
+ "phone",
475
+ "mobile",
476
+ "cell",
477
+ "ssn",
478
+ "social_security",
479
+ "national_id",
480
+ "tax_id",
481
+ "credit_card",
482
+ "cc_number",
483
+ "card_number",
484
+ "cvv",
485
+ "ccv",
486
+ "token",
487
+ "api_key",
488
+ "apikey",
489
+ "auth_token",
490
+ "session",
491
+ "address",
492
+ "street",
493
+ "city",
494
+ "zip",
495
+ "postal",
496
+ "dob",
497
+ "date_of_birth",
498
+ "birthday",
499
+ "birthdate",
500
+ "salary",
501
+ "income",
502
+ "bank",
503
+ "account_number",
504
+ "routing",
368
505
  }
369
506
 
370
507
 
371
508
  def has_sensitive_columns(columns: List[str]) -> bool:
372
509
  """
373
510
  Check if any column name suggests sensitive data.
374
-
511
+
375
512
  Args:
376
513
  columns: List of column names or column dictionaries
377
-
514
+
378
515
  Returns:
379
516
  bool: True if sensitive columns detected
380
-
517
+
381
518
  Examples:
382
519
  >>> has_sensitive_columns(['id', 'username', 'password'])
383
520
  True
@@ -386,19 +523,19 @@ def has_sensitive_columns(columns: List[str]) -> bool:
386
523
  """
387
524
  if not columns:
388
525
  return False
389
-
526
+
390
527
  for col in columns:
391
528
  # Handle both string column names and dict with 'name' key
392
529
  if isinstance(col, dict):
393
- col_name = col.get('name', col.get('column', ''))
530
+ col_name = col.get("name", col.get("column", ""))
394
531
  else:
395
532
  col_name = str(col)
396
-
533
+
397
534
  col_lower = col_name.lower()
398
-
535
+
399
536
  # Check if any sensitive keyword appears in column name
400
537
  for pattern in SENSITIVE_COLUMN_KEYWORDS:
401
538
  if pattern in col_lower:
402
539
  return True
403
-
540
+
404
541
  return False