empathy-framework 4.6.6__py3-none-any.whl → 4.7.0__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.
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/METADATA +7 -6
- empathy_framework-4.7.0.dist-info/RECORD +354 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/top_level.txt +0 -2
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
- empathy_llm_toolkit/agent_factory/__init__.py +6 -6
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
- empathy_llm_toolkit/agents_md/__init__.py +22 -0
- empathy_llm_toolkit/agents_md/loader.py +218 -0
- empathy_llm_toolkit/agents_md/parser.py +271 -0
- empathy_llm_toolkit/agents_md/registry.py +307 -0
- empathy_llm_toolkit/commands/__init__.py +51 -0
- empathy_llm_toolkit/commands/context.py +375 -0
- empathy_llm_toolkit/commands/loader.py +301 -0
- empathy_llm_toolkit/commands/models.py +231 -0
- empathy_llm_toolkit/commands/parser.py +371 -0
- empathy_llm_toolkit/commands/registry.py +429 -0
- empathy_llm_toolkit/config/__init__.py +8 -8
- empathy_llm_toolkit/config/unified.py +3 -7
- empathy_llm_toolkit/context/__init__.py +22 -0
- empathy_llm_toolkit/context/compaction.py +455 -0
- empathy_llm_toolkit/context/manager.py +434 -0
- empathy_llm_toolkit/hooks/__init__.py +24 -0
- empathy_llm_toolkit/hooks/config.py +306 -0
- empathy_llm_toolkit/hooks/executor.py +289 -0
- empathy_llm_toolkit/hooks/registry.py +302 -0
- empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
- empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
- empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
- empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
- empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
- empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
- empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
- empathy_llm_toolkit/learning/__init__.py +30 -0
- empathy_llm_toolkit/learning/evaluator.py +438 -0
- empathy_llm_toolkit/learning/extractor.py +514 -0
- empathy_llm_toolkit/learning/storage.py +560 -0
- empathy_llm_toolkit/providers.py +4 -11
- empathy_llm_toolkit/security/__init__.py +17 -17
- empathy_llm_toolkit/utils/tokens.py +2 -5
- empathy_os/__init__.py +202 -70
- empathy_os/cache_monitor.py +5 -3
- empathy_os/cli/__init__.py +11 -55
- empathy_os/cli/__main__.py +29 -15
- empathy_os/cli/commands/inspection.py +21 -12
- empathy_os/cli/commands/memory.py +4 -12
- empathy_os/cli/commands/profiling.py +198 -0
- empathy_os/cli/commands/utilities.py +27 -7
- empathy_os/cli.py +28 -57
- empathy_os/cli_unified.py +525 -1164
- empathy_os/cost_tracker.py +9 -3
- empathy_os/dashboard/server.py +200 -2
- empathy_os/hot_reload/__init__.py +7 -7
- empathy_os/hot_reload/config.py +6 -7
- empathy_os/hot_reload/integration.py +35 -35
- empathy_os/hot_reload/reloader.py +57 -57
- empathy_os/hot_reload/watcher.py +28 -28
- empathy_os/hot_reload/websocket.py +2 -2
- empathy_os/memory/__init__.py +11 -4
- empathy_os/memory/claude_memory.py +1 -1
- empathy_os/memory/cross_session.py +8 -12
- empathy_os/memory/edges.py +6 -6
- empathy_os/memory/file_session.py +770 -0
- empathy_os/memory/graph.py +30 -30
- empathy_os/memory/nodes.py +6 -6
- empathy_os/memory/short_term.py +15 -9
- empathy_os/memory/unified.py +606 -140
- empathy_os/meta_workflows/agent_creator.py +3 -9
- empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
- empathy_os/meta_workflows/form_engine.py +6 -18
- empathy_os/meta_workflows/intent_detector.py +64 -24
- empathy_os/meta_workflows/models.py +3 -1
- empathy_os/meta_workflows/pattern_learner.py +13 -31
- empathy_os/meta_workflows/plan_generator.py +55 -47
- empathy_os/meta_workflows/session_context.py +2 -3
- empathy_os/meta_workflows/workflow.py +20 -51
- empathy_os/models/cli.py +2 -2
- empathy_os/models/tasks.py +1 -2
- empathy_os/models/telemetry.py +4 -1
- empathy_os/models/token_estimator.py +3 -1
- empathy_os/monitoring/alerts.py +938 -9
- empathy_os/monitoring/alerts_cli.py +346 -183
- empathy_os/orchestration/execution_strategies.py +12 -29
- empathy_os/orchestration/pattern_learner.py +20 -26
- empathy_os/orchestration/real_tools.py +6 -15
- empathy_os/platform_utils.py +2 -1
- empathy_os/plugins/__init__.py +2 -2
- empathy_os/plugins/base.py +64 -64
- empathy_os/plugins/registry.py +32 -32
- empathy_os/project_index/index.py +49 -15
- empathy_os/project_index/models.py +1 -2
- empathy_os/project_index/reports.py +1 -1
- empathy_os/project_index/scanner.py +1 -0
- empathy_os/redis_memory.py +10 -7
- empathy_os/resilience/__init__.py +1 -1
- empathy_os/resilience/health.py +10 -10
- empathy_os/routing/__init__.py +7 -7
- empathy_os/routing/chain_executor.py +37 -37
- empathy_os/routing/classifier.py +36 -36
- empathy_os/routing/smart_router.py +40 -40
- empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
- empathy_os/scaffolding/__init__.py +8 -8
- empathy_os/scaffolding/__main__.py +1 -1
- empathy_os/scaffolding/cli.py +28 -28
- empathy_os/socratic/__init__.py +3 -19
- empathy_os/socratic/ab_testing.py +25 -36
- empathy_os/socratic/blueprint.py +38 -38
- empathy_os/socratic/cli.py +34 -20
- empathy_os/socratic/collaboration.py +30 -28
- empathy_os/socratic/domain_templates.py +9 -1
- empathy_os/socratic/embeddings.py +17 -13
- empathy_os/socratic/engine.py +135 -70
- empathy_os/socratic/explainer.py +70 -60
- empathy_os/socratic/feedback.py +24 -19
- empathy_os/socratic/forms.py +15 -10
- empathy_os/socratic/generator.py +51 -35
- empathy_os/socratic/llm_analyzer.py +25 -23
- empathy_os/socratic/mcp_server.py +99 -159
- empathy_os/socratic/session.py +19 -13
- empathy_os/socratic/storage.py +98 -67
- empathy_os/socratic/success.py +38 -27
- empathy_os/socratic/visual_editor.py +51 -39
- empathy_os/socratic/web_ui.py +99 -66
- empathy_os/telemetry/cli.py +3 -1
- empathy_os/telemetry/usage_tracker.py +1 -3
- empathy_os/test_generator/__init__.py +3 -3
- empathy_os/test_generator/cli.py +28 -28
- empathy_os/test_generator/generator.py +64 -66
- empathy_os/test_generator/risk_analyzer.py +11 -11
- empathy_os/vscode_bridge.py +173 -0
- empathy_os/workflows/__init__.py +212 -120
- empathy_os/workflows/batch_processing.py +8 -24
- empathy_os/workflows/bug_predict.py +1 -1
- empathy_os/workflows/code_review.py +20 -5
- empathy_os/workflows/code_review_pipeline.py +13 -8
- empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
- empathy_os/workflows/manage_documentation.py +1 -0
- empathy_os/workflows/orchestrated_health_check.py +6 -11
- empathy_os/workflows/orchestrated_release_prep.py +3 -3
- empathy_os/workflows/pr_review.py +18 -10
- empathy_os/workflows/progressive/__init__.py +2 -12
- empathy_os/workflows/progressive/cli.py +14 -37
- empathy_os/workflows/progressive/core.py +12 -12
- empathy_os/workflows/progressive/orchestrator.py +166 -144
- empathy_os/workflows/progressive/reports.py +22 -31
- empathy_os/workflows/progressive/telemetry.py +8 -14
- empathy_os/workflows/progressive/test_gen.py +29 -48
- empathy_os/workflows/progressive/workflow.py +31 -70
- empathy_os/workflows/release_prep.py +21 -6
- empathy_os/workflows/release_prep_crew.py +1 -0
- empathy_os/workflows/secure_release.py +13 -6
- empathy_os/workflows/security_audit.py +8 -3
- empathy_os/workflows/test_coverage_boost_crew.py +3 -2
- empathy_os/workflows/test_maintenance_crew.py +1 -0
- empathy_os/workflows/test_runner.py +16 -12
- empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
- empathy_software_plugin/cli.py +0 -122
- coach_wizards/__init__.py +0 -45
- coach_wizards/accessibility_wizard.py +0 -91
- coach_wizards/api_wizard.py +0 -91
- coach_wizards/base_wizard.py +0 -209
- coach_wizards/cicd_wizard.py +0 -91
- coach_wizards/code_reviewer_README.md +0 -60
- coach_wizards/code_reviewer_wizard.py +0 -180
- coach_wizards/compliance_wizard.py +0 -91
- coach_wizards/database_wizard.py +0 -91
- coach_wizards/debugging_wizard.py +0 -91
- coach_wizards/documentation_wizard.py +0 -91
- coach_wizards/generate_wizards.py +0 -347
- coach_wizards/localization_wizard.py +0 -173
- coach_wizards/migration_wizard.py +0 -91
- coach_wizards/monitoring_wizard.py +0 -91
- coach_wizards/observability_wizard.py +0 -91
- coach_wizards/performance_wizard.py +0 -91
- coach_wizards/prompt_engineering_wizard.py +0 -661
- coach_wizards/refactoring_wizard.py +0 -91
- coach_wizards/scaling_wizard.py +0 -90
- coach_wizards/security_wizard.py +0 -92
- coach_wizards/testing_wizard.py +0 -91
- empathy_framework-4.6.6.dist-info/RECORD +0 -410
- empathy_llm_toolkit/wizards/__init__.py +0 -43
- empathy_llm_toolkit/wizards/base_wizard.py +0 -364
- empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
- empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
- empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
- empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
- empathy_os/wizard_factory_cli.py +0 -170
- empathy_software_plugin/wizards/__init__.py +0 -42
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
- empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
- empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
- empathy_software_plugin/wizards/base_wizard.py +0 -288
- empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
- empathy_software_plugin/wizards/code_review_wizard.py +0 -604
- empathy_software_plugin/wizards/debugging/__init__.py +0 -50
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
- empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
- empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
- empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
- empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
- empathy_software_plugin/wizards/debugging/verification.py +0 -369
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
- empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
- empathy_software_plugin/wizards/performance/__init__.py +0 -9
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
- empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
- empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
- empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
- empathy_software_plugin/wizards/security/__init__.py +0 -32
- empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
- empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
- empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
- empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
- empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
- empathy_software_plugin/wizards/testing/__init__.py +0 -27
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
- empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
- empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
- empathy_software_plugin/wizards/testing_wizard.py +0 -274
- wizards/__init__.py +0 -82
- wizards/admission_assessment_wizard.py +0 -644
- wizards/care_plan.py +0 -321
- wizards/clinical_assessment.py +0 -769
- wizards/discharge_planning.py +0 -77
- wizards/discharge_summary_wizard.py +0 -468
- wizards/dosage_calculation.py +0 -497
- wizards/incident_report_wizard.py +0 -454
- wizards/medication_reconciliation.py +0 -85
- wizards/nursing_assessment.py +0 -171
- wizards/patient_education.py +0 -654
- wizards/quality_improvement.py +0 -705
- wizards/sbar_report.py +0 -324
- wizards/sbar_wizard.py +0 -608
- wizards/shift_handoff_wizard.py +0 -535
- wizards/soap_note_wizard.py +0 -679
- wizards/treatment_plan.py +0 -15
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/WHEEL +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
"""Exploit Analyzer (Level 4)
|
|
2
|
-
|
|
3
|
-
Analyzes which vulnerabilities are actually exploitable.
|
|
4
|
-
|
|
5
|
-
This is Level 4 Anticipatory Empathy - predicting which security issues
|
|
6
|
-
will actually be exploited in the wild.
|
|
7
|
-
|
|
8
|
-
Copyright 2025 Smart AI Memory, LLC
|
|
9
|
-
Licensed under Fair Source 0.9
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from dataclasses import dataclass
|
|
13
|
-
from typing import Any
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@dataclass
|
|
17
|
-
class ExploitabilityAssessment:
|
|
18
|
-
"""Assessment of how exploitable a vulnerability is"""
|
|
19
|
-
|
|
20
|
-
vulnerability: dict[str, Any]
|
|
21
|
-
exploitability: str # "CRITICAL", "HIGH", "MEDIUM", "LOW"
|
|
22
|
-
accessibility: str # "public", "authenticated", "internal"
|
|
23
|
-
attack_complexity: str # "low", "medium", "high"
|
|
24
|
-
exploit_likelihood: float # 0.0 to 1.0
|
|
25
|
-
reasoning: list[str]
|
|
26
|
-
real_world_examples: list[str]
|
|
27
|
-
mitigation_urgency: str
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ExploitAnalyzer:
|
|
31
|
-
"""Analyzes exploitability of security vulnerabilities.
|
|
32
|
-
|
|
33
|
-
Level 4: Predicts which vulnerabilities will actually be exploited.
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
def __init__(self):
|
|
37
|
-
# Known attack patterns from real-world incidents
|
|
38
|
-
self.active_attack_patterns = {
|
|
39
|
-
"SQL Injection": {
|
|
40
|
-
"likelihood": 0.9,
|
|
41
|
-
"reason": "Actively scanned by automated tools",
|
|
42
|
-
"examples": ["SQLMap", "Havij", "automated bots"],
|
|
43
|
-
},
|
|
44
|
-
"Command Injection": {
|
|
45
|
-
"likelihood": 0.95,
|
|
46
|
-
"reason": "Direct remote code execution - high value target",
|
|
47
|
-
"examples": ["Log4Shell", "Shellshock"],
|
|
48
|
-
},
|
|
49
|
-
"Hardcoded Credentials": {
|
|
50
|
-
"likelihood": 0.85,
|
|
51
|
-
"reason": "Credentials harvested from GitHub leaks",
|
|
52
|
-
"examples": ["GitHub scanning bots", "credential stuffing"],
|
|
53
|
-
},
|
|
54
|
-
"Cross-Site Scripting": {
|
|
55
|
-
"likelihood": 0.7,
|
|
56
|
-
"reason": "Common in web apps, automated scanners detect",
|
|
57
|
-
"examples": ["BeEF", "XSS Hunter"],
|
|
58
|
-
},
|
|
59
|
-
"Insecure Deserialization": {
|
|
60
|
-
"likelihood": 0.8,
|
|
61
|
-
"reason": "Remote code execution vector",
|
|
62
|
-
"examples": ["Java deserialization attacks"],
|
|
63
|
-
},
|
|
64
|
-
"Path Traversal": {
|
|
65
|
-
"likelihood": 0.75,
|
|
66
|
-
"reason": "File system access, automated detection",
|
|
67
|
-
"examples": ["Directory traversal attacks"],
|
|
68
|
-
},
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
def assess_exploitability(
|
|
72
|
-
self,
|
|
73
|
-
vulnerability: dict[str, Any],
|
|
74
|
-
context: dict[str, Any] | None = None,
|
|
75
|
-
) -> ExploitabilityAssessment:
|
|
76
|
-
"""Assess how exploitable a vulnerability is.
|
|
77
|
-
|
|
78
|
-
Args:
|
|
79
|
-
vulnerability: Detected vulnerability
|
|
80
|
-
context: Additional context (endpoint exposure, auth, etc.)
|
|
81
|
-
|
|
82
|
-
Returns:
|
|
83
|
-
ExploitabilityAssessment
|
|
84
|
-
|
|
85
|
-
Example:
|
|
86
|
-
>>> vuln = {"name": "SQL Injection", "severity": "CRITICAL", ...}
|
|
87
|
-
>>> assessment = analyzer.assess_exploitability(vuln, {
|
|
88
|
-
... "endpoint_public": True,
|
|
89
|
-
... "has_auth": False
|
|
90
|
-
... })
|
|
91
|
-
>>> print(f"Exploitability: {assessment.exploitability}")
|
|
92
|
-
|
|
93
|
-
"""
|
|
94
|
-
context = context or {}
|
|
95
|
-
|
|
96
|
-
vuln_name = vulnerability.get("name", "Unknown")
|
|
97
|
-
|
|
98
|
-
# Get base attack pattern info
|
|
99
|
-
attack_info = self.active_attack_patterns.get(
|
|
100
|
-
vuln_name,
|
|
101
|
-
{"likelihood": 0.5, "reason": "Unknown attack pattern", "examples": []},
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
# Determine accessibility
|
|
105
|
-
accessibility = self._determine_accessibility(vulnerability, context)
|
|
106
|
-
|
|
107
|
-
# Determine attack complexity
|
|
108
|
-
attack_complexity = self._determine_attack_complexity(vulnerability, context)
|
|
109
|
-
|
|
110
|
-
# Calculate exploit likelihood
|
|
111
|
-
exploit_likelihood = self._calculate_exploit_likelihood(
|
|
112
|
-
attack_info["likelihood"],
|
|
113
|
-
accessibility,
|
|
114
|
-
attack_complexity,
|
|
115
|
-
vulnerability.get("severity", "MEDIUM"),
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
# Generate reasoning
|
|
119
|
-
reasoning = self._generate_reasoning(
|
|
120
|
-
vulnerability,
|
|
121
|
-
accessibility,
|
|
122
|
-
attack_complexity,
|
|
123
|
-
attack_info,
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
# Determine exploitability rating
|
|
127
|
-
exploitability = self._determine_exploitability_rating(exploit_likelihood)
|
|
128
|
-
|
|
129
|
-
# Determine mitigation urgency
|
|
130
|
-
mitigation_urgency = self._determine_mitigation_urgency(
|
|
131
|
-
exploitability,
|
|
132
|
-
accessibility,
|
|
133
|
-
vulnerability.get("severity", "MEDIUM"),
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
return ExploitabilityAssessment(
|
|
137
|
-
vulnerability=vulnerability,
|
|
138
|
-
exploitability=exploitability,
|
|
139
|
-
accessibility=accessibility,
|
|
140
|
-
attack_complexity=attack_complexity,
|
|
141
|
-
exploit_likelihood=exploit_likelihood,
|
|
142
|
-
reasoning=reasoning,
|
|
143
|
-
real_world_examples=attack_info.get("examples", []),
|
|
144
|
-
mitigation_urgency=mitigation_urgency,
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
def _determine_accessibility(
|
|
148
|
-
self,
|
|
149
|
-
vulnerability: dict[str, Any],
|
|
150
|
-
context: dict[str, Any],
|
|
151
|
-
) -> str:
|
|
152
|
-
"""Determine if vulnerability is publicly accessible"""
|
|
153
|
-
# Check context clues
|
|
154
|
-
if context.get("endpoint_public") is True:
|
|
155
|
-
return "public"
|
|
156
|
-
|
|
157
|
-
if context.get("endpoint_public") is False:
|
|
158
|
-
return "internal"
|
|
159
|
-
|
|
160
|
-
if context.get("requires_authentication"):
|
|
161
|
-
return "authenticated"
|
|
162
|
-
|
|
163
|
-
# Infer from file path
|
|
164
|
-
file_path = vulnerability.get("file_path", "")
|
|
165
|
-
|
|
166
|
-
if any(p in file_path.lower() for p in ["api", "public", "web", "routes"]):
|
|
167
|
-
return "public"
|
|
168
|
-
|
|
169
|
-
if any(p in file_path.lower() for p in ["admin", "internal"]):
|
|
170
|
-
return "internal"
|
|
171
|
-
|
|
172
|
-
# Default to public for web-related vulnerabilities
|
|
173
|
-
if vulnerability.get("category") in ["injection", "cross_site_scripting"]:
|
|
174
|
-
return "public"
|
|
175
|
-
|
|
176
|
-
return "authenticated"
|
|
177
|
-
|
|
178
|
-
def _determine_attack_complexity(
|
|
179
|
-
self,
|
|
180
|
-
vulnerability: dict[str, Any],
|
|
181
|
-
context: dict[str, Any],
|
|
182
|
-
) -> str:
|
|
183
|
-
"""Determine attack complexity"""
|
|
184
|
-
vuln_name = vulnerability.get("name", "")
|
|
185
|
-
|
|
186
|
-
# Low complexity attacks
|
|
187
|
-
if any(
|
|
188
|
-
v in vuln_name for v in ["SQL Injection", "Command Injection", "Hardcoded Credentials"]
|
|
189
|
-
):
|
|
190
|
-
return "low"
|
|
191
|
-
|
|
192
|
-
# Medium complexity
|
|
193
|
-
if any(v in vuln_name for v in ["XSS", "CSRF", "Path Traversal"]):
|
|
194
|
-
return "medium"
|
|
195
|
-
|
|
196
|
-
# High complexity
|
|
197
|
-
if any(v in vuln_name for v in ["Deserialization", "Race Condition"]):
|
|
198
|
-
return "high"
|
|
199
|
-
|
|
200
|
-
return "medium"
|
|
201
|
-
|
|
202
|
-
def _calculate_exploit_likelihood(
|
|
203
|
-
self,
|
|
204
|
-
base_likelihood: float,
|
|
205
|
-
accessibility: str,
|
|
206
|
-
attack_complexity: str,
|
|
207
|
-
severity: str,
|
|
208
|
-
) -> float:
|
|
209
|
-
"""Calculate overall exploit likelihood"""
|
|
210
|
-
likelihood = base_likelihood
|
|
211
|
-
|
|
212
|
-
# Adjust for accessibility
|
|
213
|
-
if accessibility == "public":
|
|
214
|
-
likelihood *= 1.2 # More likely if publicly accessible
|
|
215
|
-
elif accessibility == "authenticated":
|
|
216
|
-
likelihood *= 0.8
|
|
217
|
-
elif accessibility == "internal":
|
|
218
|
-
likelihood *= 0.5
|
|
219
|
-
|
|
220
|
-
# Adjust for attack complexity
|
|
221
|
-
complexity_multipliers = {"low": 1.2, "medium": 1.0, "high": 0.7}
|
|
222
|
-
likelihood *= complexity_multipliers.get(attack_complexity, 1.0)
|
|
223
|
-
|
|
224
|
-
# Adjust for severity
|
|
225
|
-
if severity == "CRITICAL":
|
|
226
|
-
likelihood *= 1.1
|
|
227
|
-
|
|
228
|
-
# Cap at 1.0
|
|
229
|
-
return min(likelihood, 1.0)
|
|
230
|
-
|
|
231
|
-
def _generate_reasoning(
|
|
232
|
-
self,
|
|
233
|
-
vulnerability: dict[str, Any],
|
|
234
|
-
accessibility: str,
|
|
235
|
-
attack_complexity: str,
|
|
236
|
-
attack_info: dict[str, Any],
|
|
237
|
-
) -> list[str]:
|
|
238
|
-
"""Generate reasoning for exploitability assessment"""
|
|
239
|
-
reasoning = []
|
|
240
|
-
|
|
241
|
-
# Accessibility reasoning
|
|
242
|
-
if accessibility == "public":
|
|
243
|
-
reasoning.append("Endpoint is publicly accessible")
|
|
244
|
-
elif accessibility == "authenticated":
|
|
245
|
-
reasoning.append("Requires authentication - reduces attack surface")
|
|
246
|
-
else:
|
|
247
|
-
reasoning.append("Internal access only - limited exposure")
|
|
248
|
-
|
|
249
|
-
# Attack complexity reasoning
|
|
250
|
-
if attack_complexity == "low":
|
|
251
|
-
reasoning.append("Low attack complexity - easy to exploit")
|
|
252
|
-
elif attack_complexity == "high":
|
|
253
|
-
reasoning.append("High attack complexity - requires expertise")
|
|
254
|
-
|
|
255
|
-
# Pattern-based reasoning
|
|
256
|
-
if attack_info.get("reason"):
|
|
257
|
-
reasoning.append(f"In our experience: {attack_info['reason']}")
|
|
258
|
-
|
|
259
|
-
return reasoning
|
|
260
|
-
|
|
261
|
-
def _determine_exploitability_rating(self, exploit_likelihood: float) -> str:
|
|
262
|
-
"""Determine exploitability rating"""
|
|
263
|
-
if exploit_likelihood > 0.8:
|
|
264
|
-
return "CRITICAL"
|
|
265
|
-
if exploit_likelihood > 0.6:
|
|
266
|
-
return "HIGH"
|
|
267
|
-
if exploit_likelihood > 0.4:
|
|
268
|
-
return "MEDIUM"
|
|
269
|
-
return "LOW"
|
|
270
|
-
|
|
271
|
-
def _determine_mitigation_urgency(
|
|
272
|
-
self,
|
|
273
|
-
exploitability: str,
|
|
274
|
-
accessibility: str,
|
|
275
|
-
severity: str,
|
|
276
|
-
) -> str:
|
|
277
|
-
"""Determine how urgently to mitigate"""
|
|
278
|
-
if exploitability == "CRITICAL" and accessibility == "public":
|
|
279
|
-
return "IMMEDIATE - Fix before next deployment"
|
|
280
|
-
|
|
281
|
-
if exploitability == "CRITICAL" or (exploitability == "HIGH" and accessibility == "public"):
|
|
282
|
-
return "URGENT - Fix within 24 hours"
|
|
283
|
-
|
|
284
|
-
if exploitability == "HIGH" or severity == "CRITICAL":
|
|
285
|
-
return "HIGH - Fix within 1 week"
|
|
286
|
-
|
|
287
|
-
if exploitability == "MEDIUM":
|
|
288
|
-
return "MEDIUM - Fix in next sprint"
|
|
289
|
-
|
|
290
|
-
return "LOW - Schedule for future sprint"
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
"""OWASP Top 10 Pattern Detection
|
|
2
|
-
|
|
3
|
-
Detects security vulnerabilities based on OWASP Top 10.
|
|
4
|
-
|
|
5
|
-
Copyright 2025 Smart AI Memory, LLC
|
|
6
|
-
Licensed under Fair Source 0.9
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import re
|
|
10
|
-
from dataclasses import dataclass
|
|
11
|
-
from enum import Enum
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class OWASPCategory(Enum):
|
|
16
|
-
"""OWASP Top 10 categories"""
|
|
17
|
-
|
|
18
|
-
INJECTION = "injection"
|
|
19
|
-
BROKEN_AUTH = "broken_authentication"
|
|
20
|
-
SENSITIVE_DATA = "sensitive_data_exposure"
|
|
21
|
-
CRYPTOGRAPHIC_FAILURES = "cryptographic_failures"
|
|
22
|
-
XML_EXTERNAL = "xml_external_entities"
|
|
23
|
-
BROKEN_ACCESS = "broken_access_control"
|
|
24
|
-
SECURITY_MISCONFIG = "security_misconfiguration"
|
|
25
|
-
XSS = "cross_site_scripting"
|
|
26
|
-
INSECURE_DESERIALIZATION = "insecure_deserialization"
|
|
27
|
-
COMPONENTS_VULNS = "components_with_known_vulnerabilities"
|
|
28
|
-
INSUFFICIENT_LOGGING = "insufficient_logging"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@dataclass
|
|
32
|
-
class SecurityPattern:
|
|
33
|
-
"""Security vulnerability pattern"""
|
|
34
|
-
|
|
35
|
-
category: OWASPCategory
|
|
36
|
-
name: str
|
|
37
|
-
patterns: list[str] # Regex patterns
|
|
38
|
-
severity: str # "CRITICAL", "HIGH", "MEDIUM", "LOW"
|
|
39
|
-
description: str
|
|
40
|
-
example_vulnerable: str
|
|
41
|
-
example_safe: str
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class OWASPPatternDetector:
|
|
45
|
-
"""Detects OWASP Top 10 vulnerability patterns in code."""
|
|
46
|
-
|
|
47
|
-
def __init__(self):
|
|
48
|
-
self.patterns = self._build_pattern_library()
|
|
49
|
-
|
|
50
|
-
def _build_pattern_library(self) -> list[SecurityPattern]:
|
|
51
|
-
"""Build library of OWASP patterns"""
|
|
52
|
-
return [
|
|
53
|
-
# SQL Injection
|
|
54
|
-
SecurityPattern(
|
|
55
|
-
category=OWASPCategory.INJECTION,
|
|
56
|
-
name="SQL Injection",
|
|
57
|
-
patterns=[
|
|
58
|
-
r"f['\"]SELECT .+?\{.+?\}", # F-string with SQL
|
|
59
|
-
r"f['\"]INSERT .+?\{.+?\}",
|
|
60
|
-
r"f['\"]UPDATE .+?\{.+?\}",
|
|
61
|
-
r"f['\"]DELETE .+?\{.+?\}",
|
|
62
|
-
r"['\"]SELECT.*['\"][\s]*\+", # String concatenation with SQL
|
|
63
|
-
r"['\"]INSERT.*['\"][\s]*\+",
|
|
64
|
-
r"['\"]UPDATE.*['\"][\s]*\+",
|
|
65
|
-
r"['\"]DELETE.*['\"][\s]*\+",
|
|
66
|
-
r"execute\s*\(\s*f['\"]", # execute with f-string
|
|
67
|
-
r"cursor\.execute.*?%.*?%", # Old-style formatting
|
|
68
|
-
],
|
|
69
|
-
severity="CRITICAL",
|
|
70
|
-
description="SQL query built with string concatenation - vulnerable to injection",
|
|
71
|
-
example_vulnerable="cursor.execute(f\"SELECT * FROM users WHERE name='{username}'\")",
|
|
72
|
-
example_safe="cursor.execute('SELECT * FROM users WHERE name = ?', (username,))",
|
|
73
|
-
),
|
|
74
|
-
# Command Injection
|
|
75
|
-
SecurityPattern(
|
|
76
|
-
category=OWASPCategory.INJECTION,
|
|
77
|
-
name="Command Injection",
|
|
78
|
-
patterns=[
|
|
79
|
-
r"os\.system\s*\(.*?\+", # os.system with concatenation
|
|
80
|
-
r"subprocess\.\w+\(.*?shell\s*=\s*True", # shell=True is dangerous
|
|
81
|
-
r"eval\s*\(", # eval() is very dangerous
|
|
82
|
-
r"exec\s*\(", # exec() is very dangerous
|
|
83
|
-
],
|
|
84
|
-
severity="CRITICAL",
|
|
85
|
-
description="Command execution with unsanitized input",
|
|
86
|
-
example_vulnerable="os.system('rm ' + user_file)",
|
|
87
|
-
example_safe="subprocess.run(['rm', user_file])",
|
|
88
|
-
),
|
|
89
|
-
# XSS (Cross-Site Scripting)
|
|
90
|
-
SecurityPattern(
|
|
91
|
-
category=OWASPCategory.XSS,
|
|
92
|
-
name="Cross-Site Scripting",
|
|
93
|
-
patterns=[
|
|
94
|
-
r"innerHTML\s*=", # Direct innerHTML assignment
|
|
95
|
-
r"document\.write\s*\(", # document.write with user input
|
|
96
|
-
r"\.html\s*\(.*?\+", # jQuery .html() with concatenation
|
|
97
|
-
r"dangerouslySetInnerHTML", # React dangerous prop
|
|
98
|
-
],
|
|
99
|
-
severity="HIGH",
|
|
100
|
-
description="User input rendered without sanitization",
|
|
101
|
-
example_vulnerable="element.innerHTML = userInput",
|
|
102
|
-
example_safe="element.textContent = userInput",
|
|
103
|
-
),
|
|
104
|
-
# Hardcoded Credentials
|
|
105
|
-
SecurityPattern(
|
|
106
|
-
category=OWASPCategory.BROKEN_AUTH,
|
|
107
|
-
name="Hardcoded Credentials",
|
|
108
|
-
patterns=[
|
|
109
|
-
r"password\s*=\s*['\"][^'\"]+['\"]", # password = "secret"
|
|
110
|
-
r"api_key\s*=\s*['\"][^'\"]+['\"]",
|
|
111
|
-
r"secret[\w_]*\s*=\s*['\"][^'\"]+['\"]", # secret or secret_token or secret_key
|
|
112
|
-
r"token\s*=\s*['\"][A-Za-z0-9]{20,}['\"]",
|
|
113
|
-
],
|
|
114
|
-
severity="CRITICAL",
|
|
115
|
-
description="Hardcoded credentials in source code",
|
|
116
|
-
example_vulnerable="password = 'admin123'",
|
|
117
|
-
example_safe="password = os.environ.get('DB_PASSWORD')",
|
|
118
|
-
),
|
|
119
|
-
# Weak Cryptography
|
|
120
|
-
SecurityPattern(
|
|
121
|
-
category=OWASPCategory.CRYPTOGRAPHIC_FAILURES,
|
|
122
|
-
name="Weak Cryptography",
|
|
123
|
-
patterns=[
|
|
124
|
-
r"MD5\(", # MD5 is broken
|
|
125
|
-
r"SHA1\(", # SHA1 is weak
|
|
126
|
-
r"DES\(", # DES is obsolete
|
|
127
|
-
r"Random\(", # Not cryptographically secure
|
|
128
|
-
],
|
|
129
|
-
severity="HIGH",
|
|
130
|
-
description="Weak or broken cryptographic algorithm",
|
|
131
|
-
example_vulnerable="hashlib.md5(password)",
|
|
132
|
-
example_safe="hashlib.sha256(password)",
|
|
133
|
-
),
|
|
134
|
-
# Missing Authentication
|
|
135
|
-
SecurityPattern(
|
|
136
|
-
category=OWASPCategory.BROKEN_AUTH,
|
|
137
|
-
name="Missing Authentication Check",
|
|
138
|
-
patterns=[
|
|
139
|
-
r"@app\.route.*?\n(?!.*@.*require.*auth).*?def", # Flask route without auth
|
|
140
|
-
r"router\.\w+\(.*?\).*?\n(?!.*auth).*?function", # Express route without auth
|
|
141
|
-
],
|
|
142
|
-
severity="CRITICAL",
|
|
143
|
-
description="Endpoint lacks authentication check",
|
|
144
|
-
example_vulnerable="@app.route('/admin')\\ndef admin_panel():",
|
|
145
|
-
example_safe="@app.route('/admin')\\n@require_auth\\ndef admin_panel():",
|
|
146
|
-
),
|
|
147
|
-
# Insecure Deserialization
|
|
148
|
-
SecurityPattern(
|
|
149
|
-
category=OWASPCategory.INSECURE_DESERIALIZATION,
|
|
150
|
-
name="Insecure Deserialization",
|
|
151
|
-
patterns=[
|
|
152
|
-
r"pickle\.loads?\(", # Python pickle is unsafe
|
|
153
|
-
r"yaml\.load\((?!.*Loader\s*=)", # PyYAML unsafe load
|
|
154
|
-
r"eval\(", # Deserializing code
|
|
155
|
-
],
|
|
156
|
-
severity="CRITICAL",
|
|
157
|
-
description="Deserializing untrusted data",
|
|
158
|
-
example_vulnerable="pickle.loads(user_data)",
|
|
159
|
-
example_safe="json.loads(user_data)",
|
|
160
|
-
),
|
|
161
|
-
# Sensitive Data Logging
|
|
162
|
-
SecurityPattern(
|
|
163
|
-
category=OWASPCategory.SENSITIVE_DATA,
|
|
164
|
-
name="Sensitive Data in Logs",
|
|
165
|
-
patterns=[
|
|
166
|
-
r"log.*password",
|
|
167
|
-
r"print.*password",
|
|
168
|
-
r"console\.log.*password",
|
|
169
|
-
r"log.*credit.*card",
|
|
170
|
-
],
|
|
171
|
-
severity="HIGH",
|
|
172
|
-
description="Logging sensitive data",
|
|
173
|
-
example_vulnerable="logger.info(f'Login: {username}:{password}')",
|
|
174
|
-
example_safe="logger.info(f'Login: {username}:***')",
|
|
175
|
-
),
|
|
176
|
-
# Path Traversal
|
|
177
|
-
SecurityPattern(
|
|
178
|
-
category=OWASPCategory.BROKEN_ACCESS,
|
|
179
|
-
name="Path Traversal",
|
|
180
|
-
patterns=[
|
|
181
|
-
r"open\s*\(.*?user.*?\)", # open() with user input
|
|
182
|
-
r"file_path\s*=.*?\+", # Path concatenation
|
|
183
|
-
],
|
|
184
|
-
severity="HIGH",
|
|
185
|
-
description="File path built from user input",
|
|
186
|
-
example_vulnerable="open('/uploads/' + user_file)",
|
|
187
|
-
example_safe="open(os.path.join(UPLOAD_DIR, secure_filename(user_file)))",
|
|
188
|
-
),
|
|
189
|
-
# CSRF Missing Protection
|
|
190
|
-
SecurityPattern(
|
|
191
|
-
category=OWASPCategory.BROKEN_ACCESS,
|
|
192
|
-
name="Missing CSRF Protection",
|
|
193
|
-
patterns=[
|
|
194
|
-
r"@app\.route.*?methods\s*=\s*\[.*?POST.*?\].*?\n(?!.*csrf).*?def",
|
|
195
|
-
],
|
|
196
|
-
severity="MEDIUM",
|
|
197
|
-
description="POST endpoint without CSRF protection",
|
|
198
|
-
example_vulnerable="@app.route('/transfer', methods=['POST'])\\ndef transfer():",
|
|
199
|
-
example_safe="@app.route('/transfer', methods=['POST'])\\n@csrf_protect\\ndef transfer():",
|
|
200
|
-
),
|
|
201
|
-
]
|
|
202
|
-
|
|
203
|
-
def detect_vulnerabilities(self, code: str, file_path: str = "") -> list[dict[str, Any]]:
|
|
204
|
-
"""Detect vulnerabilities in code.
|
|
205
|
-
|
|
206
|
-
Args:
|
|
207
|
-
code: Source code to analyze
|
|
208
|
-
file_path: Path to file (for context)
|
|
209
|
-
|
|
210
|
-
Returns:
|
|
211
|
-
List of detected vulnerabilities
|
|
212
|
-
|
|
213
|
-
"""
|
|
214
|
-
vulnerabilities = []
|
|
215
|
-
|
|
216
|
-
for pattern_def in self.patterns:
|
|
217
|
-
for regex_pattern in pattern_def.patterns:
|
|
218
|
-
matches = re.finditer(regex_pattern, code, re.MULTILINE | re.IGNORECASE)
|
|
219
|
-
|
|
220
|
-
for match in matches:
|
|
221
|
-
# Find line number
|
|
222
|
-
line_number = code[: match.start()].count("\n") + 1
|
|
223
|
-
|
|
224
|
-
vulnerabilities.append(
|
|
225
|
-
{
|
|
226
|
-
"category": pattern_def.category.value,
|
|
227
|
-
"name": pattern_def.name,
|
|
228
|
-
"severity": pattern_def.severity,
|
|
229
|
-
"file_path": file_path,
|
|
230
|
-
"line_number": line_number,
|
|
231
|
-
"matched_code": match.group(0),
|
|
232
|
-
"description": pattern_def.description,
|
|
233
|
-
"example_safe": pattern_def.example_safe,
|
|
234
|
-
},
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
return vulnerabilities
|
|
238
|
-
|
|
239
|
-
def get_pattern_by_category(self, category: OWASPCategory) -> list[SecurityPattern]:
|
|
240
|
-
"""Get all patterns for a category"""
|
|
241
|
-
return [p for p in self.patterns if p.category == category]
|