empathy-framework 4.6.6__py3-none-any.whl → 4.7.1__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 (273) hide show
  1. empathy_framework-4.7.1.dist-info/METADATA +690 -0
  2. empathy_framework-4.7.1.dist-info/RECORD +379 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -2
  4. empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
  5. empathy_llm_toolkit/agent_factory/__init__.py +6 -6
  6. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
  7. empathy_llm_toolkit/agents_md/__init__.py +22 -0
  8. empathy_llm_toolkit/agents_md/loader.py +218 -0
  9. empathy_llm_toolkit/agents_md/parser.py +271 -0
  10. empathy_llm_toolkit/agents_md/registry.py +307 -0
  11. empathy_llm_toolkit/commands/__init__.py +51 -0
  12. empathy_llm_toolkit/commands/context.py +375 -0
  13. empathy_llm_toolkit/commands/loader.py +301 -0
  14. empathy_llm_toolkit/commands/models.py +231 -0
  15. empathy_llm_toolkit/commands/parser.py +371 -0
  16. empathy_llm_toolkit/commands/registry.py +429 -0
  17. empathy_llm_toolkit/config/__init__.py +8 -8
  18. empathy_llm_toolkit/config/unified.py +3 -7
  19. empathy_llm_toolkit/context/__init__.py +22 -0
  20. empathy_llm_toolkit/context/compaction.py +455 -0
  21. empathy_llm_toolkit/context/manager.py +434 -0
  22. empathy_llm_toolkit/hooks/__init__.py +24 -0
  23. empathy_llm_toolkit/hooks/config.py +306 -0
  24. empathy_llm_toolkit/hooks/executor.py +289 -0
  25. empathy_llm_toolkit/hooks/registry.py +302 -0
  26. empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
  27. empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
  28. empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
  29. empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
  30. empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
  31. empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
  32. empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
  33. empathy_llm_toolkit/learning/__init__.py +30 -0
  34. empathy_llm_toolkit/learning/evaluator.py +438 -0
  35. empathy_llm_toolkit/learning/extractor.py +514 -0
  36. empathy_llm_toolkit/learning/storage.py +560 -0
  37. empathy_llm_toolkit/providers.py +4 -11
  38. empathy_llm_toolkit/security/__init__.py +17 -17
  39. empathy_llm_toolkit/utils/tokens.py +2 -5
  40. empathy_os/__init__.py +202 -70
  41. empathy_os/cache_monitor.py +5 -3
  42. empathy_os/cli/__init__.py +11 -55
  43. empathy_os/cli/__main__.py +29 -15
  44. empathy_os/cli/commands/inspection.py +21 -12
  45. empathy_os/cli/commands/memory.py +4 -12
  46. empathy_os/cli/commands/profiling.py +198 -0
  47. empathy_os/cli/commands/utilities.py +27 -7
  48. empathy_os/cli.py +28 -57
  49. empathy_os/cli_unified.py +525 -1164
  50. empathy_os/cost_tracker.py +9 -3
  51. empathy_os/dashboard/server.py +200 -2
  52. empathy_os/hot_reload/__init__.py +7 -7
  53. empathy_os/hot_reload/config.py +6 -7
  54. empathy_os/hot_reload/integration.py +35 -35
  55. empathy_os/hot_reload/reloader.py +57 -57
  56. empathy_os/hot_reload/watcher.py +28 -28
  57. empathy_os/hot_reload/websocket.py +2 -2
  58. empathy_os/memory/__init__.py +11 -4
  59. empathy_os/memory/claude_memory.py +1 -1
  60. empathy_os/memory/cross_session.py +8 -12
  61. empathy_os/memory/edges.py +6 -6
  62. empathy_os/memory/file_session.py +770 -0
  63. empathy_os/memory/graph.py +30 -30
  64. empathy_os/memory/nodes.py +6 -6
  65. empathy_os/memory/short_term.py +15 -9
  66. empathy_os/memory/unified.py +606 -140
  67. empathy_os/meta_workflows/agent_creator.py +3 -9
  68. empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
  69. empathy_os/meta_workflows/form_engine.py +6 -18
  70. empathy_os/meta_workflows/intent_detector.py +64 -24
  71. empathy_os/meta_workflows/models.py +3 -1
  72. empathy_os/meta_workflows/pattern_learner.py +13 -31
  73. empathy_os/meta_workflows/plan_generator.py +55 -47
  74. empathy_os/meta_workflows/session_context.py +2 -3
  75. empathy_os/meta_workflows/workflow.py +20 -51
  76. empathy_os/models/cli.py +2 -2
  77. empathy_os/models/tasks.py +1 -2
  78. empathy_os/models/telemetry.py +4 -1
  79. empathy_os/models/token_estimator.py +3 -1
  80. empathy_os/monitoring/alerts.py +938 -9
  81. empathy_os/monitoring/alerts_cli.py +346 -183
  82. empathy_os/orchestration/execution_strategies.py +12 -29
  83. empathy_os/orchestration/pattern_learner.py +20 -26
  84. empathy_os/orchestration/real_tools.py +6 -15
  85. empathy_os/platform_utils.py +2 -1
  86. empathy_os/plugins/__init__.py +2 -2
  87. empathy_os/plugins/base.py +64 -64
  88. empathy_os/plugins/registry.py +32 -32
  89. empathy_os/project_index/index.py +49 -15
  90. empathy_os/project_index/models.py +1 -2
  91. empathy_os/project_index/reports.py +1 -1
  92. empathy_os/project_index/scanner.py +1 -0
  93. empathy_os/redis_memory.py +10 -7
  94. empathy_os/resilience/__init__.py +1 -1
  95. empathy_os/resilience/health.py +10 -10
  96. empathy_os/routing/__init__.py +7 -7
  97. empathy_os/routing/chain_executor.py +37 -37
  98. empathy_os/routing/classifier.py +36 -36
  99. empathy_os/routing/smart_router.py +40 -40
  100. empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
  101. empathy_os/scaffolding/__init__.py +8 -8
  102. empathy_os/scaffolding/__main__.py +1 -1
  103. empathy_os/scaffolding/cli.py +28 -28
  104. empathy_os/socratic/__init__.py +3 -19
  105. empathy_os/socratic/ab_testing.py +25 -36
  106. empathy_os/socratic/blueprint.py +38 -38
  107. empathy_os/socratic/cli.py +34 -20
  108. empathy_os/socratic/collaboration.py +30 -28
  109. empathy_os/socratic/domain_templates.py +9 -1
  110. empathy_os/socratic/embeddings.py +17 -13
  111. empathy_os/socratic/engine.py +135 -70
  112. empathy_os/socratic/explainer.py +70 -60
  113. empathy_os/socratic/feedback.py +24 -19
  114. empathy_os/socratic/forms.py +15 -10
  115. empathy_os/socratic/generator.py +51 -35
  116. empathy_os/socratic/llm_analyzer.py +25 -23
  117. empathy_os/socratic/mcp_server.py +99 -159
  118. empathy_os/socratic/session.py +19 -13
  119. empathy_os/socratic/storage.py +98 -67
  120. empathy_os/socratic/success.py +38 -27
  121. empathy_os/socratic/visual_editor.py +51 -39
  122. empathy_os/socratic/web_ui.py +99 -66
  123. empathy_os/telemetry/cli.py +3 -1
  124. empathy_os/telemetry/usage_tracker.py +1 -3
  125. empathy_os/test_generator/__init__.py +3 -3
  126. empathy_os/test_generator/cli.py +28 -28
  127. empathy_os/test_generator/generator.py +64 -66
  128. empathy_os/test_generator/risk_analyzer.py +11 -11
  129. empathy_os/vscode_bridge 2.py +173 -0
  130. empathy_os/vscode_bridge.py +173 -0
  131. empathy_os/workflows/__init__.py +212 -120
  132. empathy_os/workflows/batch_processing.py +8 -24
  133. empathy_os/workflows/bug_predict.py +1 -1
  134. empathy_os/workflows/code_review.py +20 -5
  135. empathy_os/workflows/code_review_pipeline.py +13 -8
  136. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  137. empathy_os/workflows/manage_documentation.py +1 -0
  138. empathy_os/workflows/orchestrated_health_check.py +6 -11
  139. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  140. empathy_os/workflows/pr_review.py +18 -10
  141. empathy_os/workflows/progressive/README 2.md +454 -0
  142. empathy_os/workflows/progressive/__init__ 2.py +92 -0
  143. empathy_os/workflows/progressive/__init__.py +2 -12
  144. empathy_os/workflows/progressive/cli 2.py +242 -0
  145. empathy_os/workflows/progressive/cli.py +14 -37
  146. empathy_os/workflows/progressive/core 2.py +488 -0
  147. empathy_os/workflows/progressive/core.py +12 -12
  148. empathy_os/workflows/progressive/orchestrator 2.py +701 -0
  149. empathy_os/workflows/progressive/orchestrator.py +166 -144
  150. empathy_os/workflows/progressive/reports 2.py +528 -0
  151. empathy_os/workflows/progressive/reports.py +22 -31
  152. empathy_os/workflows/progressive/telemetry 2.py +280 -0
  153. empathy_os/workflows/progressive/telemetry.py +8 -14
  154. empathy_os/workflows/progressive/test_gen 2.py +514 -0
  155. empathy_os/workflows/progressive/test_gen.py +29 -48
  156. empathy_os/workflows/progressive/workflow 2.py +628 -0
  157. empathy_os/workflows/progressive/workflow.py +31 -70
  158. empathy_os/workflows/release_prep.py +21 -6
  159. empathy_os/workflows/release_prep_crew.py +1 -0
  160. empathy_os/workflows/secure_release.py +13 -6
  161. empathy_os/workflows/security_audit.py +8 -3
  162. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  163. empathy_os/workflows/test_maintenance_crew.py +1 -0
  164. empathy_os/workflows/test_runner.py +16 -12
  165. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  166. empathy_software_plugin/cli.py +0 -122
  167. patterns/README.md +119 -0
  168. patterns/__init__.py +95 -0
  169. patterns/behavior.py +298 -0
  170. patterns/code_review_memory.json +441 -0
  171. patterns/core.py +97 -0
  172. patterns/debugging.json +3763 -0
  173. patterns/empathy.py +268 -0
  174. patterns/health_check_memory.json +505 -0
  175. patterns/input.py +161 -0
  176. patterns/memory_graph.json +8 -0
  177. patterns/refactoring_memory.json +1113 -0
  178. patterns/registry.py +663 -0
  179. patterns/security_memory.json +8 -0
  180. patterns/structural.py +415 -0
  181. patterns/validation.py +194 -0
  182. coach_wizards/__init__.py +0 -45
  183. coach_wizards/accessibility_wizard.py +0 -91
  184. coach_wizards/api_wizard.py +0 -91
  185. coach_wizards/base_wizard.py +0 -209
  186. coach_wizards/cicd_wizard.py +0 -91
  187. coach_wizards/code_reviewer_README.md +0 -60
  188. coach_wizards/code_reviewer_wizard.py +0 -180
  189. coach_wizards/compliance_wizard.py +0 -91
  190. coach_wizards/database_wizard.py +0 -91
  191. coach_wizards/debugging_wizard.py +0 -91
  192. coach_wizards/documentation_wizard.py +0 -91
  193. coach_wizards/generate_wizards.py +0 -347
  194. coach_wizards/localization_wizard.py +0 -173
  195. coach_wizards/migration_wizard.py +0 -91
  196. coach_wizards/monitoring_wizard.py +0 -91
  197. coach_wizards/observability_wizard.py +0 -91
  198. coach_wizards/performance_wizard.py +0 -91
  199. coach_wizards/prompt_engineering_wizard.py +0 -661
  200. coach_wizards/refactoring_wizard.py +0 -91
  201. coach_wizards/scaling_wizard.py +0 -90
  202. coach_wizards/security_wizard.py +0 -92
  203. coach_wizards/testing_wizard.py +0 -91
  204. empathy_framework-4.6.6.dist-info/METADATA +0 -1597
  205. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  206. empathy_llm_toolkit/wizards/__init__.py +0 -43
  207. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  208. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  209. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  210. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  211. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  212. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  213. empathy_os/wizard_factory_cli.py +0 -170
  214. empathy_software_plugin/wizards/__init__.py +0 -42
  215. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  216. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  217. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  218. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  219. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  220. empathy_software_plugin/wizards/base_wizard.py +0 -288
  221. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  222. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  223. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  224. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  225. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  226. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  227. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  228. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  229. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  230. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  231. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  232. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  233. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  234. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  235. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  236. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  237. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  238. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  239. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  240. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  241. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  242. empathy_software_plugin/wizards/security/__init__.py +0 -32
  243. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  244. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  245. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  246. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  247. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  248. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  249. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  250. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  251. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  252. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  253. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  254. wizards/__init__.py +0 -82
  255. wizards/admission_assessment_wizard.py +0 -644
  256. wizards/care_plan.py +0 -321
  257. wizards/clinical_assessment.py +0 -769
  258. wizards/discharge_planning.py +0 -77
  259. wizards/discharge_summary_wizard.py +0 -468
  260. wizards/dosage_calculation.py +0 -497
  261. wizards/incident_report_wizard.py +0 -454
  262. wizards/medication_reconciliation.py +0 -85
  263. wizards/nursing_assessment.py +0 -171
  264. wizards/patient_education.py +0 -654
  265. wizards/quality_improvement.py +0 -705
  266. wizards/sbar_report.py +0 -324
  267. wizards/sbar_wizard.py +0 -608
  268. wizards/shift_handoff_wizard.py +0 -535
  269. wizards/soap_note_wizard.py +0 -679
  270. wizards/treatment_plan.py +0 -15
  271. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/WHEEL +0 -0
  272. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
  273. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,604 +0,0 @@
1
- """Vulnerability Scanner for Security Analysis Wizard
2
-
3
- Comprehensive vulnerability detection including:
4
- - Dependency vulnerabilities (CVE matching)
5
- - Secret detection (API keys, passwords, tokens)
6
- - Configuration security issues
7
- - OWASP Top 10 patterns
8
- - Code security anti-patterns
9
-
10
- Copyright 2025 Smart-AI-Memory
11
- Licensed under Fair Source License 0.9
12
- """
13
-
14
- import json
15
- import re
16
- import subprocess
17
- from dataclasses import dataclass
18
- from enum import Enum
19
- from pathlib import Path
20
-
21
-
22
- class VulnerabilityType(Enum):
23
- """Types of security vulnerabilities"""
24
-
25
- SQL_INJECTION = "sql_injection"
26
- XSS = "xss"
27
- COMMAND_INJECTION = "command_injection"
28
- PATH_TRAVERSAL = "path_traversal"
29
- HARDCODED_SECRET = "hardcoded_secret"
30
- WEAK_CRYPTO = "weak_crypto"
31
- INSECURE_DESERIALIZATION = "insecure_deserialization"
32
- XXE = "xxe" # XML External Entity
33
- CSRF = "csrf"
34
- SSRF = "ssrf" # Server-Side Request Forgery
35
- DEPENDENCY_VULN = "dependency_vulnerability"
36
- INSECURE_CONFIG = "insecure_configuration"
37
-
38
-
39
- class Severity(Enum):
40
- """CVSS-based severity levels"""
41
-
42
- CRITICAL = "critical" # CVSS 9.0-10.0
43
- HIGH = "high" # CVSS 7.0-8.9
44
- MEDIUM = "medium" # CVSS 4.0-6.9
45
- LOW = "low" # CVSS 0.1-3.9
46
- INFO = "info" # Informational
47
-
48
-
49
- @dataclass
50
- class Vulnerability:
51
- """Represents a detected security vulnerability"""
52
-
53
- vuln_type: VulnerabilityType
54
- severity: Severity
55
- file_path: str
56
- line_number: int
57
- description: str
58
- evidence: str # Code snippet or pattern matched
59
- cwe_id: str | None = None # Common Weakness Enumeration
60
- cve_id: str | None = None # Common Vulnerabilities and Exposures
61
- cvss_score: float | None = None
62
- remediation: str | None = None
63
- references: list[str] | None = None
64
-
65
- def __post_init__(self):
66
- if self.references is None:
67
- self.references = []
68
-
69
-
70
- @dataclass
71
- class DependencyVulnerability:
72
- """Vulnerability in a dependency package"""
73
-
74
- package_name: str
75
- installed_version: str
76
- vulnerable_versions: str
77
- fixed_version: str | None
78
- cve_id: str
79
- cvss_score: float
80
- severity: Severity
81
- description: str
82
- references: list[str]
83
-
84
-
85
- @dataclass
86
- class VulnerabilityScanReport:
87
- """Complete vulnerability scan report"""
88
-
89
- total_issues: int
90
- critical_count: int
91
- high_count: int
92
- medium_count: int
93
- low_count: int
94
- info_count: int
95
- vulnerabilities: list[Vulnerability]
96
- dependency_vulnerabilities: list[DependencyVulnerability]
97
- files_scanned: int
98
- scan_duration: float # seconds
99
-
100
-
101
- class VulnerabilityScanner:
102
- """Comprehensive vulnerability scanner for Python projects.
103
-
104
- Detects:
105
- - OWASP Top 10 vulnerabilities
106
- - Hardcoded secrets
107
- - Insecure dependencies
108
- - Configuration issues
109
- - Common security anti-patterns
110
- """
111
-
112
- def __init__(self):
113
- self._init_secret_patterns()
114
- self._init_injection_patterns()
115
- self._init_crypto_patterns()
116
-
117
- def _init_secret_patterns(self):
118
- """Initialize patterns for secret detection"""
119
- self.secret_patterns = {
120
- "AWS Access Key": re.compile(r"AKIA[0-9A-Z]{16}"),
121
- "AWS Secret Key": re.compile(
122
- r'aws_secret_access_key\s*=\s*["\']([^"\']+)["\']',
123
- re.IGNORECASE,
124
- ),
125
- "API Key": re.compile(
126
- r'api[_-]?key\s*[=:]\s*["\']([a-zA-Z0-9_\-]{20,})["\']',
127
- re.IGNORECASE,
128
- ),
129
- "Private Key": re.compile(r"-----BEGIN (RSA |EC |DSA )?PRIVATE KEY-----"),
130
- "GitHub Token": re.compile(r"ghp_[a-zA-Z0-9]{36}"),
131
- "Generic Secret": re.compile(
132
- r'(secret|password|passwd|pwd)\s*[=:]\s*["\']([^"\']{8,})["\']',
133
- re.IGNORECASE,
134
- ),
135
- "JWT Token": re.compile(r"eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*"),
136
- "Database URL": re.compile(r"(mysql|postgresql|mongodb)://[^:]+:[^@]+@", re.IGNORECASE),
137
- "Slack Token": re.compile(r"xox[baprs]-[0-9a-zA-Z]{10,48}"),
138
- "Stripe Key": re.compile(r"sk_live_[0-9a-zA-Z]{24}"),
139
- }
140
-
141
- def _init_injection_patterns(self):
142
- """Initialize patterns for injection vulnerabilities"""
143
- self.injection_patterns = {
144
- VulnerabilityType.SQL_INJECTION: [
145
- (re.compile(r'execute\(["\'].*%s.*["\']'), "String formatting in SQL"),
146
- (re.compile(r'execute\(["\'].*\+.*["\']'), "String concatenation in SQL"),
147
- (re.compile(r'execute\(f["\'].*\{.*\}.*["\']'), "f-string in SQL"),
148
- (re.compile(r"raw_sql\s*=.*\+"), "SQL string concatenation"),
149
- ],
150
- VulnerabilityType.COMMAND_INJECTION: [
151
- (re.compile(r"os\.system\(.*\+"), "os.system with concatenation"),
152
- (
153
- re.compile(r"subprocess\.(call|run|Popen)\(.*shell\s*=\s*True"),
154
- "subprocess with shell=True",
155
- ),
156
- (re.compile(r"eval\("), "Use of eval()"),
157
- (re.compile(r"exec\("), "Use of exec()"),
158
- ],
159
- VulnerabilityType.PATH_TRAVERSAL: [
160
- (re.compile(r'open\(["\'].*\+'), "Path concatenation in file open"),
161
- (re.compile(r"open\(.*\.format\("), "String formatting in file path"),
162
- (re.compile(r"Path\(.*\+"), "Path concatenation"),
163
- ],
164
- VulnerabilityType.XSS: [
165
- (re.compile(r"\.innerHTML\s*="), "Direct innerHTML assignment"),
166
- (re.compile(r"document\.write\("), "document.write usage"),
167
- (re.compile(r"render_template_string\(.*\+"), "Unsafe template rendering"),
168
- ],
169
- }
170
-
171
- def _init_crypto_patterns(self):
172
- """Initialize patterns for cryptographic issues"""
173
- self.crypto_patterns = {
174
- "Weak Hash (MD5)": re.compile(r"hashlib\.md5\("),
175
- "Weak Hash (SHA1)": re.compile(r"hashlib\.sha1\("),
176
- "Weak Cipher (DES)": re.compile(r"Crypto\.Cipher\.(DES|DES3)"),
177
- "Weak Cipher (RC4)": re.compile(r"Crypto\.Cipher\.ARC4"),
178
- "Hardcoded IV": re.compile(r'iv\s*=\s*b?["\'][^"\']+["\']'),
179
- "Random without seed": re.compile(r"random\.random\(\)"),
180
- }
181
-
182
- def scan_file(self, file_path: Path) -> list[Vulnerability]:
183
- """Scan a single file for vulnerabilities
184
-
185
- Args:
186
- file_path: Path to file to scan
187
-
188
- Returns:
189
- List of Vulnerability objects found
190
-
191
- Raises:
192
- FileNotFoundError: If file doesn't exist
193
-
194
- """
195
- if not file_path.exists():
196
- raise FileNotFoundError(f"File not found: {file_path}")
197
-
198
- vulnerabilities = []
199
-
200
- with open(file_path, encoding="utf-8", errors="ignore") as f:
201
- content = f.read()
202
- lines = content.split("\n")
203
-
204
- # Scan for secrets
205
- vulnerabilities.extend(self._scan_for_secrets(file_path, content, lines))
206
-
207
- # Scan for injection vulnerabilities
208
- vulnerabilities.extend(self._scan_for_injections(file_path, content, lines))
209
-
210
- # Scan for crypto issues
211
- vulnerabilities.extend(self._scan_for_crypto_issues(file_path, content, lines))
212
-
213
- # Scan for insecure deserialization
214
- vulnerabilities.extend(self._scan_for_deserialization(file_path, content, lines))
215
-
216
- # Scan for CSRF issues (web frameworks)
217
- vulnerabilities.extend(self._scan_for_csrf(file_path, content, lines))
218
-
219
- return vulnerabilities
220
-
221
- def _scan_for_secrets(
222
- self,
223
- file_path: Path,
224
- content: str,
225
- lines: list[str],
226
- ) -> list[Vulnerability]:
227
- """Scan for hardcoded secrets"""
228
- vulnerabilities: list[Vulnerability] = []
229
-
230
- # Skip certain file types
231
- if file_path.suffix in [".md", ".txt", ".json", ".xml"]:
232
- return vulnerabilities
233
-
234
- for secret_type, pattern in self.secret_patterns.items():
235
- for match in pattern.finditer(content):
236
- # Find line number
237
- line_num = content[: match.start()].count("\n") + 1
238
-
239
- # Extract evidence (mask the actual secret)
240
- evidence = lines[line_num - 1] if line_num <= len(lines) else ""
241
- masked_evidence = self._mask_secret(evidence)
242
-
243
- # Determine severity
244
- if "private key" in secret_type.lower():
245
- severity = Severity.CRITICAL
246
- elif "password" in secret_type.lower():
247
- severity = Severity.HIGH
248
- else:
249
- severity = Severity.MEDIUM
250
-
251
- vuln = Vulnerability(
252
- vuln_type=VulnerabilityType.HARDCODED_SECRET,
253
- severity=severity,
254
- file_path=str(file_path),
255
- line_number=line_num,
256
- description=f"Hardcoded {secret_type} detected",
257
- evidence=masked_evidence,
258
- cwe_id="CWE-798", # Use of Hard-coded Credentials
259
- remediation="Use environment variables or secure secret management (e.g., AWS Secrets Manager, HashiCorp Vault)",
260
- references=["https://cwe.mitre.org/data/definitions/798.html"],
261
- )
262
- vulnerabilities.append(vuln)
263
-
264
- return vulnerabilities
265
-
266
- def _scan_for_injections(
267
- self,
268
- file_path: Path,
269
- content: str,
270
- lines: list[str],
271
- ) -> list[Vulnerability]:
272
- """Scan for injection vulnerabilities"""
273
- vulnerabilities = []
274
-
275
- for vuln_type, patterns in self.injection_patterns.items():
276
- for pattern, description in patterns:
277
- for match in pattern.finditer(content):
278
- line_num = content[: match.start()].count("\n") + 1
279
- evidence = lines[line_num - 1] if line_num <= len(lines) else ""
280
-
281
- # Determine severity and CWE
282
- if vuln_type == VulnerabilityType.SQL_INJECTION:
283
- severity = Severity.CRITICAL
284
- cwe_id = "CWE-89"
285
- remediation = "Use parameterized queries or an ORM with automatic escaping"
286
- elif vuln_type == VulnerabilityType.COMMAND_INJECTION:
287
- severity = Severity.CRITICAL
288
- cwe_id = "CWE-78"
289
- remediation = "Avoid shell=True, use list arguments, validate input"
290
- elif vuln_type == VulnerabilityType.XSS:
291
- severity = Severity.HIGH
292
- cwe_id = "CWE-79"
293
- remediation = (
294
- "Use proper output encoding, template engines with auto-escaping"
295
- )
296
- else:
297
- severity = Severity.HIGH
298
- cwe_id = "CWE-20"
299
- remediation = "Validate and sanitize all user input"
300
-
301
- vuln = Vulnerability(
302
- vuln_type=vuln_type,
303
- severity=severity,
304
- file_path=str(file_path),
305
- line_number=line_num,
306
- description=description,
307
- evidence=evidence.strip(),
308
- cwe_id=cwe_id,
309
- remediation=remediation,
310
- references=[
311
- f"https://cwe.mitre.org/data/definitions/{cwe_id.split('-')[1]}.html",
312
- ],
313
- )
314
- vulnerabilities.append(vuln)
315
-
316
- return vulnerabilities
317
-
318
- def _scan_for_crypto_issues(
319
- self,
320
- file_path: Path,
321
- content: str,
322
- lines: list[str],
323
- ) -> list[Vulnerability]:
324
- """Scan for cryptographic issues"""
325
- vulnerabilities = []
326
-
327
- for issue_type, pattern in self.crypto_patterns.items():
328
- for match in pattern.finditer(content):
329
- line_num = content[: match.start()].count("\n") + 1
330
- evidence = lines[line_num - 1] if line_num <= len(lines) else ""
331
-
332
- vuln = Vulnerability(
333
- vuln_type=VulnerabilityType.WEAK_CRYPTO,
334
- severity=Severity.MEDIUM,
335
- file_path=str(file_path),
336
- line_number=line_num,
337
- description=f"Weak cryptography: {issue_type}",
338
- evidence=evidence.strip(),
339
- cwe_id="CWE-327", # Use of Broken or Risky Cryptographic Algorithm
340
- remediation="Use SHA-256 or better for hashing, AES for encryption",
341
- references=["https://cwe.mitre.org/data/definitions/327.html"],
342
- )
343
- vulnerabilities.append(vuln)
344
-
345
- return vulnerabilities
346
-
347
- def _scan_for_deserialization(
348
- self,
349
- file_path: Path,
350
- content: str,
351
- lines: list[str],
352
- ) -> list[Vulnerability]:
353
- """Scan for insecure deserialization"""
354
- vulnerabilities = []
355
-
356
- # Patterns for unsafe deserialization
357
- patterns = [
358
- (
359
- re.compile(r"pickle\.loads?\("),
360
- "Use of pickle.load() - vulnerable to code execution",
361
- ),
362
- (
363
- re.compile(r"yaml\.load\((?!.*Loader=yaml\.SafeLoader)"),
364
- "Use of yaml.load() without SafeLoader",
365
- ),
366
- (re.compile(r"eval\("), "Use of eval() - code execution risk"),
367
- ]
368
-
369
- for pattern, description in patterns:
370
- for match in pattern.finditer(content):
371
- line_num = content[: match.start()].count("\n") + 1
372
- evidence = lines[line_num - 1] if line_num <= len(lines) else ""
373
-
374
- vuln = Vulnerability(
375
- vuln_type=VulnerabilityType.INSECURE_DESERIALIZATION,
376
- severity=Severity.HIGH,
377
- file_path=str(file_path),
378
- line_number=line_num,
379
- description=description,
380
- evidence=evidence.strip(),
381
- cwe_id="CWE-502", # Deserialization of Untrusted Data
382
- remediation="Use safe deserialization methods (json.loads, yaml.safe_load)",
383
- references=["https://cwe.mitre.org/data/definitions/502.html"],
384
- )
385
- vulnerabilities.append(vuln)
386
-
387
- return vulnerabilities
388
-
389
- def _scan_for_csrf(
390
- self,
391
- file_path: Path,
392
- content: str,
393
- lines: list[str],
394
- ) -> list[Vulnerability]:
395
- """Scan for CSRF vulnerabilities in web frameworks"""
396
- vulnerabilities = []
397
-
398
- # Django/Flask CSRF patterns
399
- patterns = [
400
- (
401
- re.compile(r'@app\.route\(.*methods\s*=\s*\[.*["\']POST["\'].*\]'),
402
- "POST route without CSRF protection",
403
- ),
404
- ]
405
-
406
- for pattern, _description in patterns:
407
- for match in pattern.finditer(content):
408
- # Check if CSRF protection is present nearby
409
- line_num = content[: match.start()].count("\n") + 1
410
-
411
- # Look for CSRF decorators/middleware in surrounding lines
412
- surrounding_lines = lines[max(0, line_num - 5) : min(len(lines), line_num + 3)]
413
- has_csrf_protection = any(
414
- "csrf" in line.lower() or "@login_required" in line
415
- for line in surrounding_lines
416
- )
417
-
418
- if not has_csrf_protection:
419
- evidence = lines[line_num - 1] if line_num <= len(lines) else ""
420
-
421
- vuln = Vulnerability(
422
- vuln_type=VulnerabilityType.CSRF,
423
- severity=Severity.MEDIUM,
424
- file_path=str(file_path),
425
- line_number=line_num,
426
- description="POST endpoint without CSRF protection",
427
- evidence=evidence.strip(),
428
- cwe_id="CWE-352", # Cross-Site Request Forgery
429
- remediation="Add CSRF protection (e.g., Flask-WTF, Django CSRF middleware)",
430
- references=["https://cwe.mitre.org/data/definitions/352.html"],
431
- )
432
- vulnerabilities.append(vuln)
433
-
434
- return vulnerabilities
435
-
436
- def _mask_secret(self, text: str) -> str:
437
- """Mask secrets in evidence"""
438
- # Mask anything that looks like a secret
439
- masked = re.sub(r'["\'][a-zA-Z0-9_\-/+=]{16,}["\']', '"***REDACTED***"', text)
440
- return masked
441
-
442
- def scan_dependencies(
443
- self,
444
- requirements_file: Path | None = None,
445
- ) -> list[DependencyVulnerability]:
446
- """Scan dependencies for known vulnerabilities using pip-audit
447
-
448
- Args:
449
- requirements_file: Path to requirements.txt (optional)
450
-
451
- Returns:
452
- List of DependencyVulnerability objects
453
-
454
- Note: Requires 'pip-audit' to be installed
455
-
456
- """
457
- try:
458
- # Try to run pip-audit
459
- cmd = ["pip-audit", "--format", "json"]
460
- if requirements_file:
461
- cmd.extend(["-r", str(requirements_file)])
462
-
463
- result = subprocess.run(cmd, check=False, capture_output=True, text=True, timeout=60)
464
-
465
- if result.returncode != 0:
466
- # pip-audit not installed or failed
467
- return []
468
-
469
- # Parse JSON output
470
- data = json.loads(result.stdout)
471
- return self._parse_pip_audit_output(data)
472
-
473
- except (subprocess.TimeoutExpired, FileNotFoundError, json.JSONDecodeError):
474
- # pip-audit not available or failed
475
- return []
476
-
477
- def _parse_pip_audit_output(self, data: dict) -> list[DependencyVulnerability]:
478
- """Parse pip-audit JSON output"""
479
- vulnerabilities = []
480
-
481
- for package_data in data.get("dependencies", []):
482
- package_name = package_data.get("name", "")
483
- version = package_data.get("version", "")
484
-
485
- for vuln in package_data.get("vulns", []):
486
- cve_id = vuln.get("id", "")
487
- description = vuln.get("description", "")
488
- fixed_version = (
489
- vuln.get("fix_versions", [""])[0] if vuln.get("fix_versions") else None
490
- )
491
-
492
- # Parse CVSS score
493
- cvss_score = 0.0
494
- if "aliases" in vuln:
495
- for alias in vuln["aliases"]:
496
- if "cvss" in alias:
497
- try:
498
- cvss_score = float(alias["cvss"])
499
- except (ValueError, TypeError):
500
- pass
501
-
502
- # Determine severity from CVSS
503
- if cvss_score >= 9.0:
504
- severity = Severity.CRITICAL
505
- elif cvss_score >= 7.0:
506
- severity = Severity.HIGH
507
- elif cvss_score >= 4.0:
508
- severity = Severity.MEDIUM
509
- else:
510
- severity = Severity.LOW
511
-
512
- dep_vuln = DependencyVulnerability(
513
- package_name=package_name,
514
- installed_version=version,
515
- vulnerable_versions=f"<{fixed_version}" if fixed_version else "current",
516
- fixed_version=fixed_version,
517
- cve_id=cve_id,
518
- cvss_score=cvss_score,
519
- severity=severity,
520
- description=description,
521
- references=[f"https://nvd.nist.gov/vuln/detail/{cve_id}"],
522
- )
523
- vulnerabilities.append(dep_vuln)
524
-
525
- return vulnerabilities
526
-
527
- def generate_report(
528
- self,
529
- vulnerabilities: list[Vulnerability],
530
- dependency_vulns: list[DependencyVulnerability],
531
- files_scanned: int,
532
- scan_duration: float,
533
- ) -> VulnerabilityScanReport:
534
- """Generate comprehensive scan report"""
535
- # Count by severity
536
- critical_count = sum(1 for v in vulnerabilities if v.severity == Severity.CRITICAL)
537
- high_count = sum(1 for v in vulnerabilities if v.severity == Severity.HIGH)
538
- medium_count = sum(1 for v in vulnerabilities if v.severity == Severity.MEDIUM)
539
- low_count = sum(1 for v in vulnerabilities if v.severity == Severity.LOW)
540
- info_count = sum(1 for v in vulnerabilities if v.severity == Severity.INFO)
541
-
542
- # Add dependency vulnerabilities to counts
543
- critical_count += sum(1 for v in dependency_vulns if v.severity == Severity.CRITICAL)
544
- high_count += sum(1 for v in dependency_vulns if v.severity == Severity.HIGH)
545
- medium_count += sum(1 for v in dependency_vulns if v.severity == Severity.MEDIUM)
546
- low_count += sum(1 for v in dependency_vulns if v.severity == Severity.LOW)
547
-
548
- return VulnerabilityScanReport(
549
- total_issues=len(vulnerabilities) + len(dependency_vulns),
550
- critical_count=critical_count,
551
- high_count=high_count,
552
- medium_count=medium_count,
553
- low_count=low_count,
554
- info_count=info_count,
555
- vulnerabilities=vulnerabilities,
556
- dependency_vulnerabilities=dependency_vulns,
557
- files_scanned=files_scanned,
558
- scan_duration=scan_duration,
559
- )
560
-
561
- def generate_summary(self, report: VulnerabilityScanReport) -> str:
562
- """Generate human-readable summary"""
563
- summary = []
564
- summary.append("=" * 70)
565
- summary.append("SECURITY VULNERABILITY SCAN REPORT")
566
- summary.append("=" * 70)
567
- summary.append(f"Files Scanned: {report.files_scanned}")
568
- summary.append(f"Scan Duration: {report.scan_duration:.2f}s")
569
- summary.append(f"Total Issues Found: {report.total_issues}")
570
- summary.append("")
571
- summary.append("Severity Breakdown:")
572
- summary.append(f" šŸ”“ CRITICAL: {report.critical_count}")
573
- summary.append(f" 🟠 HIGH: {report.high_count}")
574
- summary.append(f" 🟔 MEDIUM: {report.medium_count}")
575
- summary.append(f" šŸ”µ LOW: {report.low_count}")
576
- summary.append(f" ⚪ INFO: {report.info_count}")
577
- summary.append("")
578
-
579
- if report.critical_count > 0 or report.high_count > 0:
580
- summary.append("āš ļø CRITICAL & HIGH SEVERITY ISSUES:")
581
- critical_high = [
582
- v
583
- for v in report.vulnerabilities
584
- if v.severity in [Severity.CRITICAL, Severity.HIGH]
585
- ]
586
- for vuln in critical_high[:5]:
587
- summary.append(f"\n {vuln.severity.value.upper()}: {vuln.description}")
588
- summary.append(f" File: {vuln.file_path}:{vuln.line_number}")
589
- summary.append(f" Type: {vuln.vuln_type.value}")
590
- if vuln.cwe_id:
591
- summary.append(f" CWE: {vuln.cwe_id}")
592
-
593
- if report.dependency_vulnerabilities:
594
- summary.append("\nšŸ“¦ DEPENDENCY VULNERABILITIES:")
595
- for dep_vuln in report.dependency_vulnerabilities[:5]:
596
- summary.append(f"\n {dep_vuln.package_name} {dep_vuln.installed_version}")
597
- summary.append(f" {dep_vuln.cve_id} - {dep_vuln.severity.value.upper()}")
598
- summary.append(f" CVSS: {dep_vuln.cvss_score}")
599
- if dep_vuln.fixed_version:
600
- summary.append(f" Fix: Upgrade to {dep_vuln.fixed_version}")
601
-
602
- summary.append("\n" + "=" * 70)
603
-
604
- return "\n".join(summary)