correctover-runtime-guard 1.4.0__tar.gz → 2.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {correctover_runtime_guard-1.4.0 → correctover_runtime_guard-2.1.2}/PKG-INFO +30 -18
- {correctover_runtime_guard-1.4.0 → correctover_runtime_guard-2.1.2}/README.md +24 -13
- correctover_runtime_guard-2.1.2/correctover_agent/__init__.py +11 -0
- {correctover_runtime_guard-1.4.0 → correctover_runtime_guard-2.1.2}/correctover_agent/cli.py +163 -105
- {correctover_runtime_guard-1.4.0 → correctover_runtime_guard-2.1.2}/correctover_agent/guard.py +87 -8
- correctover_runtime_guard-2.1.2/correctover_agent/license.py +474 -0
- correctover_runtime_guard-2.1.2/correctover_agent/mcp_server.py +154 -0
- {correctover_runtime_guard-1.4.0 → correctover_runtime_guard-2.1.2}/pyproject.toml +5 -4
- correctover_runtime_guard-1.4.0/.gitignore +0 -3
- correctover_runtime_guard-1.4.0/.mcp.json +0 -8
- correctover_runtime_guard-1.4.0/correctover_agent/__init__.py +0 -8
- correctover_runtime_guard-1.4.0/correctover_agent/license.py +0 -211
- correctover_runtime_guard-1.4.0/correctover_agent/mcp_server.py +0 -103
- correctover_runtime_guard-1.4.0/glama.json +0 -15
- correctover_runtime_guard-1.4.0/smithery.yaml +0 -5
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: correctover-runtime-guard
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary: Real-time RCE/SSRF/credential leak interception for AI agents —
|
|
3
|
+
Version: 2.1.2
|
|
4
|
+
Summary: Real-time RCE/SSRF/credential leak interception for AI agents — MCP Server mode with diagnose_error, fault patterns, repair suggestions. Pro license required for full features.
|
|
5
5
|
Project-URL: Homepage, https://correctover.com
|
|
6
6
|
Project-URL: Repository, https://github.com/Correctover/runtime-guard
|
|
7
7
|
Project-URL: Issues, https://github.com/Correctover/runtime-guard/issues
|
|
8
|
+
Project-URL: Pricing, https://correctover.com/checkout
|
|
8
9
|
Author-email: Correctover <wangguigui@correctover.com>
|
|
9
|
-
License:
|
|
10
|
+
License: Proprietary Commercial License
|
|
10
11
|
Keywords: ai-agent,correctover,credential-leak,guardrail,interception,mcp,rce,real-time,runtime-guard,security,ssrf
|
|
11
12
|
Classifier: Development Status :: 4 - Beta
|
|
12
13
|
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License ::
|
|
14
|
+
Classifier: License :: Other/Proprietary License
|
|
14
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
17
|
Classifier: Topic :: Security
|
|
@@ -23,11 +24,11 @@ Description-Content-Type: text/markdown
|
|
|
23
24
|
|
|
24
25
|
# 🛡️ correctover-runtime-guard
|
|
25
26
|
|
|
26
|
-
**Real-time RCE/SSRF/Env Leak interception —
|
|
27
|
+
**Real-time RCE/SSRF/Env Leak interception — P50 ≈ 2011µs (local measurement, 2026-08-22).**
|
|
27
28
|
|
|
28
29
|
[](https://pypi.org/project/correctover-runtime-guard/)
|
|
29
30
|
[](https://www.python.org/downloads/)
|
|
30
|
-
[](https://correctover.com/checkout)
|
|
31
32
|
|
|
32
33
|
## Quick Start
|
|
33
34
|
|
|
@@ -47,18 +48,29 @@ Runtime guardrail for AI Agent tool calls — intercepts before execution:
|
|
|
47
48
|
|
|
48
49
|
### Performance
|
|
49
50
|
|
|
51
|
+
Local measurement on a single host (2026-08-22). Indicative only, not a vendor benchmark.
|
|
52
|
+
|
|
50
53
|
| Metric | Value |
|
|
51
54
|
|--------|-------|
|
|
52
|
-
| P50 latency |
|
|
53
|
-
| P99 latency |
|
|
54
|
-
| Overhead |
|
|
55
|
-
| Detection rate |
|
|
55
|
+
| P50 latency | ≈2011µs |
|
|
56
|
+
| P99 latency | not benchmarked |
|
|
57
|
+
| Overhead | not benchmarked |
|
|
58
|
+
| Detection rate | qualitative — real-time RCE/SSRF/Env-leak blocking |
|
|
59
|
+
|
|
60
|
+
### Evidence
|
|
61
|
+
|
|
62
|
+
Backed by CCS fault taxonomy v2.5 (verified 2026-08-22):
|
|
63
|
+
|
|
64
|
+
- **5 verified PoCs** · **3 CVEs referenced**
|
|
65
|
+
- CVE-2026-42271 → LiteLLM (CVSS 8.8, verified)
|
|
66
|
+
- CVE-2026-25536 → MCP TypeScript SDK race condition (CVSS 7.1, verified)
|
|
67
|
+
- CVE-2026-12957 → AWS Language Servers (CVSS 7.8, verified via NVD 2026-08-22)
|
|
56
68
|
|
|
57
69
|
## Free Tier
|
|
58
70
|
|
|
59
71
|
50 interceptions/day — no credit card required.
|
|
60
72
|
|
|
61
|
-
Enterprise:
|
|
73
|
+
Enterprise: ¥1,999/month — [correctover.com/checkout](https://correctover.com/checkout)
|
|
62
74
|
|
|
63
75
|
```bash
|
|
64
76
|
export CORRECTOVER_LICENSE_KEY=your-key-here
|
|
@@ -68,11 +80,11 @@ export CORRECTOVER_LICENSE_KEY=your-key-here
|
|
|
68
80
|
|
|
69
81
|
| Tool | Install | Description |
|
|
70
82
|
|------|---------|-------------|
|
|
71
|
-
| **Security Scanner** | `npx correctover-scan` | MCP config security audit
|
|
72
|
-
| **Self-Healing Test** | `pip install correctover-test` | Agent self-healing test suite |
|
|
73
|
-
| **Vulnerability Scan** | `pip install correctover-security-audit` |
|
|
74
|
-
| **Compliance Check** | `pip install correctover-compliance-check` | OAuth 2.1 + CCS v1.0 |
|
|
75
|
-
| **Runtime Guard** | `pip install correctover-runtime-guard` |
|
|
76
|
-
| **MCP Server** | `npm install correctover-mcp-server` |
|
|
83
|
+
| **Security Scanner** | `npx correctover-scan` | MCP config security audit(checks 数未核实) |
|
|
84
|
+
| **Self-Healing Test** | `pip install correctover-test` | Agent self-healing test suite(3 scenarios × 3 frameworks) |
|
|
85
|
+
| **Vulnerability Scan** | `pip install correctover-security-audit` | 32 detection rules (CCS v2.5) |
|
|
86
|
+
| **Compliance Check** | `pip install correctover-compliance-check` | OAuth 2.1 + CCS v1.0 (18 checks) |
|
|
87
|
+
| **Runtime Guard** | `pip install correctover-runtime-guard` | RCE/SSRF interception (P50 ≈ 2011µs local measurement) |
|
|
88
|
+
| **MCP Server** | `npm install correctover-mcp-server` | Compatibility package(已退役,转发至 correctover-mcp-gateway) |
|
|
77
89
|
|
|
78
90
|
**Website**: [correctover.com](https://correctover.com) · **GitHub**: [github.com/Correctover](https://github.com/Correctover)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# 🛡️ correctover-runtime-guard
|
|
2
2
|
|
|
3
|
-
**Real-time RCE/SSRF/Env Leak interception —
|
|
3
|
+
**Real-time RCE/SSRF/Env Leak interception — P50 ≈ 2011µs (local measurement, 2026-08-22).**
|
|
4
4
|
|
|
5
5
|
[](https://pypi.org/project/correctover-runtime-guard/)
|
|
6
6
|
[](https://www.python.org/downloads/)
|
|
7
|
-
[](https://correctover.com/checkout)
|
|
8
8
|
|
|
9
9
|
## Quick Start
|
|
10
10
|
|
|
@@ -24,18 +24,29 @@ Runtime guardrail for AI Agent tool calls — intercepts before execution:
|
|
|
24
24
|
|
|
25
25
|
### Performance
|
|
26
26
|
|
|
27
|
+
Local measurement on a single host (2026-08-22). Indicative only, not a vendor benchmark.
|
|
28
|
+
|
|
27
29
|
| Metric | Value |
|
|
28
30
|
|--------|-------|
|
|
29
|
-
| P50 latency |
|
|
30
|
-
| P99 latency |
|
|
31
|
-
| Overhead |
|
|
32
|
-
| Detection rate |
|
|
31
|
+
| P50 latency | ≈2011µs |
|
|
32
|
+
| P99 latency | not benchmarked |
|
|
33
|
+
| Overhead | not benchmarked |
|
|
34
|
+
| Detection rate | qualitative — real-time RCE/SSRF/Env-leak blocking |
|
|
35
|
+
|
|
36
|
+
### Evidence
|
|
37
|
+
|
|
38
|
+
Backed by CCS fault taxonomy v2.5 (verified 2026-08-22):
|
|
39
|
+
|
|
40
|
+
- **5 verified PoCs** · **3 CVEs referenced**
|
|
41
|
+
- CVE-2026-42271 → LiteLLM (CVSS 8.8, verified)
|
|
42
|
+
- CVE-2026-25536 → MCP TypeScript SDK race condition (CVSS 7.1, verified)
|
|
43
|
+
- CVE-2026-12957 → AWS Language Servers (CVSS 7.8, verified via NVD 2026-08-22)
|
|
33
44
|
|
|
34
45
|
## Free Tier
|
|
35
46
|
|
|
36
47
|
50 interceptions/day — no credit card required.
|
|
37
48
|
|
|
38
|
-
Enterprise:
|
|
49
|
+
Enterprise: ¥1,999/month — [correctover.com/checkout](https://correctover.com/checkout)
|
|
39
50
|
|
|
40
51
|
```bash
|
|
41
52
|
export CORRECTOVER_LICENSE_KEY=your-key-here
|
|
@@ -45,11 +56,11 @@ export CORRECTOVER_LICENSE_KEY=your-key-here
|
|
|
45
56
|
|
|
46
57
|
| Tool | Install | Description |
|
|
47
58
|
|------|---------|-------------|
|
|
48
|
-
| **Security Scanner** | `npx correctover-scan` | MCP config security audit
|
|
49
|
-
| **Self-Healing Test** | `pip install correctover-test` | Agent self-healing test suite |
|
|
50
|
-
| **Vulnerability Scan** | `pip install correctover-security-audit` |
|
|
51
|
-
| **Compliance Check** | `pip install correctover-compliance-check` | OAuth 2.1 + CCS v1.0 |
|
|
52
|
-
| **Runtime Guard** | `pip install correctover-runtime-guard` |
|
|
53
|
-
| **MCP Server** | `npm install correctover-mcp-server` |
|
|
59
|
+
| **Security Scanner** | `npx correctover-scan` | MCP config security audit(checks 数未核实) |
|
|
60
|
+
| **Self-Healing Test** | `pip install correctover-test` | Agent self-healing test suite(3 scenarios × 3 frameworks) |
|
|
61
|
+
| **Vulnerability Scan** | `pip install correctover-security-audit` | 32 detection rules (CCS v2.5) |
|
|
62
|
+
| **Compliance Check** | `pip install correctover-compliance-check` | OAuth 2.1 + CCS v1.0 (18 checks) |
|
|
63
|
+
| **Runtime Guard** | `pip install correctover-runtime-guard` | RCE/SSRF interception (P50 ≈ 2011µs local measurement) |
|
|
64
|
+
| **MCP Server** | `npm install correctover-mcp-server` | Compatibility package(已退役,转发至 correctover-mcp-gateway) |
|
|
54
65
|
|
|
55
66
|
**Website**: [correctover.com](https://correctover.com) · **GitHub**: [github.com/Correctover](https://github.com/Correctover)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
correctover-runtime-guard — Runtime interception for RCE/SSRF/Env leaks.
|
|
3
|
+
P50 detection latency measured at ~2,011µs on local host (2026-08-22 benchmark).
|
|
4
|
+
|
|
5
|
+
v2.1.1: NB- key decode fix (Alibaba Cloud FC payment system).
|
|
6
|
+
|
|
7
|
+
Pricing: Pro ¥199/month | Enterprise ¥1,999/month
|
|
8
|
+
Website: https://correctover.com/checkout
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
__version__ = "2.1.2"
|
{correctover_runtime_guard-1.4.0 → correctover_runtime_guard-2.1.2}/correctover_agent/cli.py
RENAMED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
correctover-runtime-guard CLI —
|
|
2
|
+
correctover-runtime-guard CLI — license-enforced freemium.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
8 detection patterns · 22µs P50 latency · cross-referenced with 52 bounty cases
|
|
4
|
+
Free: diagnose first 2 threats, no repair strategies, no live interception
|
|
5
|
+
Pro: full diagnosis + repair + live MCP interception + auto-heal
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
Pro: all threats + repair + live interception + auto-heal
|
|
10
|
-
|
|
11
|
-
Hook: "This pattern was exploited in Correctover0026 (CVSS 9.8). 3 more hidden."
|
|
7
|
+
Hook: "This pattern was exploited in Correctover0026. 3 more hidden."
|
|
12
8
|
"""
|
|
13
9
|
|
|
14
10
|
import sys
|
|
@@ -18,52 +14,55 @@ from typing import Optional
|
|
|
18
14
|
import click
|
|
19
15
|
|
|
20
16
|
from .guard import RuntimeGuard, FAULT_PATTERNS
|
|
17
|
+
from .license import LicenseValidator, LicenseExceededError
|
|
18
|
+
from . import __version__ as GUARD_VERSION
|
|
21
19
|
|
|
22
|
-
VERSION =
|
|
20
|
+
VERSION = GUARD_VERSION
|
|
23
21
|
CTA_URL = "https://correctover.com/checkout"
|
|
24
|
-
|
|
22
|
+
# Local measurement 2026-08-22; do not present as a vendor benchmark.
|
|
23
|
+
LATENCY_P50 = "2011µs"
|
|
25
24
|
FREE_THREAT_PREVIEW = 2
|
|
26
25
|
|
|
27
26
|
# Ammunition: map runtime guard pattern IDs to CCS taxonomy evidence
|
|
28
27
|
GUARD_AMMO = {
|
|
29
28
|
"RCE-001": {
|
|
30
29
|
"taxonomy_id": "CMD-001",
|
|
31
|
-
"cwe": "CWE-78", "cve": "CVE-2026-42271", "cvss":
|
|
30
|
+
"cwe": "CWE-78", "cve": "CVE-2026-42271", "cvss": 8.8,
|
|
32
31
|
"bounty_cases": ["Correctover0026", "Correctover0027", "Correctover0028", "Correctover0030"],
|
|
33
32
|
"verified_poc": True,
|
|
34
|
-
"real_target": "
|
|
33
|
+
"real_target": "LiteLLM (CVSS 8.8)",
|
|
35
34
|
"consequence": "Remote code execution — full system compromise",
|
|
36
35
|
},
|
|
37
36
|
"RCE-002": {
|
|
38
37
|
"taxonomy_id": "CMD-001",
|
|
39
|
-
"cwe": "CWE-78", "cve": "CVE-2026-42271", "cvss":
|
|
38
|
+
"cwe": "CWE-78", "cve": "CVE-2026-42271", "cvss": 8.8,
|
|
40
39
|
"bounty_cases": ["Correctover0049"],
|
|
41
40
|
"verified_poc": True,
|
|
42
|
-
"real_target": "
|
|
41
|
+
"real_target": "LiteLLM (CVSS 8.8)",
|
|
43
42
|
"consequence": "Destructive command execution — data loss or system destruction",
|
|
44
43
|
},
|
|
45
44
|
"SSRF-001": {
|
|
46
45
|
"taxonomy_id": "SSRF-001",
|
|
47
|
-
"cwe": "CWE-918", "cve": "CVE-2026-25536", "cvss":
|
|
46
|
+
"cwe": "CWE-918", "cve": "CVE-2026-25536", "cvss": 7.1,
|
|
48
47
|
"bounty_cases": ["Correctover0006", "Correctover0022", "Correctover0023"],
|
|
49
48
|
"verified_poc": True,
|
|
50
|
-
"real_target": "
|
|
49
|
+
"real_target": "MCP TypeScript SDK race condition (CVSS 7.1)",
|
|
51
50
|
"consequence": "SSRF — cloud metadata access, internal service enumeration",
|
|
52
51
|
},
|
|
53
52
|
"SSRF-002": {
|
|
54
53
|
"taxonomy_id": "SSRF-001",
|
|
55
|
-
"cwe": "CWE-918", "cve": "CVE-2026-25536", "cvss":
|
|
54
|
+
"cwe": "CWE-918", "cve": "CVE-2026-25536", "cvss": 7.1,
|
|
56
55
|
"bounty_cases": ["Correctover0044", "Correctover0046", "Correctover0047"],
|
|
57
56
|
"verified_poc": True,
|
|
58
|
-
"real_target": "
|
|
57
|
+
"real_target": "MCP TypeScript SDK race condition (CVSS 7.1)",
|
|
59
58
|
"consequence": "Internal network access — cloud metadata credential theft",
|
|
60
59
|
},
|
|
61
60
|
"ENV-001": {
|
|
62
61
|
"taxonomy_id": "CRED-001",
|
|
63
|
-
"cwe": "CWE-200", "cve": "CVE-2026-12957", "cvss":
|
|
62
|
+
"cwe": "CWE-200", "cve": "CVE-2026-12957", "cvss": 7.8, # 12957 real target = AWS Language Servers; CVSS verified via NVD 2026-08-22 (v3.1 7.8 HIGH / v4.0 8.5)
|
|
64
63
|
"bounty_cases": [],
|
|
65
64
|
"verified_poc": True,
|
|
66
|
-
"real_target": "
|
|
65
|
+
"real_target": "AWS Language Servers (CVSS 7.8, NVD 2026-08-22)",
|
|
67
66
|
"consequence": "Environment variable leak — API key and secret exposure",
|
|
68
67
|
},
|
|
69
68
|
"ENV-002": {
|
|
@@ -93,16 +92,49 @@ GUARD_AMMO = {
|
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
license_key = LicenseValidator.get_license_from_env()
|
|
95
|
+
def _get_license_status():
|
|
96
|
+
"""Get current license status. Returns (is_pro, validator)."""
|
|
99
97
|
validator = LicenseValidator("correctover-runtime-guard")
|
|
98
|
+
license_key = LicenseValidator.get_license_from_env()
|
|
100
99
|
if license_key:
|
|
101
100
|
validator.set_license_key(license_key)
|
|
102
101
|
status = validator.check_license()
|
|
103
102
|
return status["tier"] == "pro", validator
|
|
104
103
|
|
|
105
104
|
|
|
105
|
+
def _require_pro():
|
|
106
|
+
"""Require Pro license. Exits with error if free tier."""
|
|
107
|
+
is_pro, validator = _get_license_status()
|
|
108
|
+
if not is_pro:
|
|
109
|
+
click.echo(
|
|
110
|
+
f"\n{'━'*55}\n"
|
|
111
|
+
f"🔒 This feature requires a Pro license.\n\n"
|
|
112
|
+
f" Free tier: limited diagnostics only\n"
|
|
113
|
+
f" Pro tier: full scanning + repair + live interception\n\n"
|
|
114
|
+
f" → {CTA_URL}\n"
|
|
115
|
+
f" → export CORRECTOVER_LICENSE_KEY=<your-key>\n"
|
|
116
|
+
f"{'━'*55}\n"
|
|
117
|
+
)
|
|
118
|
+
sys.exit(1)
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _gate_scan(validator, is_pro: bool):
|
|
123
|
+
"""Free tier: enforce FREE_DAILY_LIMIT (50 scans/day) before running a scan."""
|
|
124
|
+
if is_pro:
|
|
125
|
+
return
|
|
126
|
+
status = validator.check_license()
|
|
127
|
+
if not status.get("can_scan", True):
|
|
128
|
+
limit = status.get("daily_limit", 50)
|
|
129
|
+
click.echo(
|
|
130
|
+
f"\n{'━'*55}\n"
|
|
131
|
+
f"🔒 Free tier daily scan limit reached ({limit}/day).\n"
|
|
132
|
+
f" → Upgrade to Pro for unlimited scans: {CTA_URL}\n"
|
|
133
|
+
f"{'━'*55}\n"
|
|
134
|
+
)
|
|
135
|
+
sys.exit(2)
|
|
136
|
+
|
|
137
|
+
|
|
106
138
|
def _get_ammo(pattern_id: str) -> dict:
|
|
107
139
|
"""Get ammunition data for a runtime guard pattern."""
|
|
108
140
|
return GUARD_AMMO.get(pattern_id, {})
|
|
@@ -113,10 +145,16 @@ def _get_ammo(pattern_id: str) -> dict:
|
|
|
113
145
|
def cli():
|
|
114
146
|
"""🛡️ Correctover Runtime Guard — real-time RCE/SSRF/credential leak interception.
|
|
115
147
|
|
|
116
|
-
|
|
117
|
-
Backed by 52 ZDI bounty cases ·
|
|
148
|
+
2011µs P50 detection (local measurement). 8 fault patterns cross-referenced with CCS v2.5 taxonomy.
|
|
149
|
+
Backed by 52 ZDI bounty cases · 5 verified PoCs · 3 CVEs.
|
|
118
150
|
"""
|
|
119
|
-
|
|
151
|
+
# Windows GBK terminals crash on non-ASCII output (UnicodeEncodeError).
|
|
152
|
+
# Force UTF-8 at the CLI output entry; reconfigure() exists in Py3.7+.
|
|
153
|
+
try:
|
|
154
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
155
|
+
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
|
156
|
+
except (AttributeError, ValueError):
|
|
157
|
+
pass
|
|
120
158
|
|
|
121
159
|
|
|
122
160
|
@cli.command()
|
|
@@ -124,29 +162,26 @@ def cli():
|
|
|
124
162
|
@click.option("--host", default="0.0.0.0")
|
|
125
163
|
@click.option("--port", default=8080)
|
|
126
164
|
def start(transport, host, port):
|
|
127
|
-
"""Start the Runtime Guard MCP server.
|
|
128
|
-
is_pro, validator = _check_license()
|
|
165
|
+
"""Start the Runtime Guard MCP server. PRO REQUIRED.
|
|
129
166
|
|
|
130
|
-
|
|
167
|
+
Live interception and auto-heal require a valid Pro license.
|
|
168
|
+
Free tier cannot start the MCP server.
|
|
169
|
+
"""
|
|
170
|
+
_require_pro()
|
|
171
|
+
|
|
172
|
+
is_pro, validator = _get_license_status()
|
|
173
|
+
GREEN = "\033[92m"; CYAN = "\033[96m"
|
|
131
174
|
BOLD = "\033[1m"; DIM = "\033[2m"; RESET = "\033[0m"
|
|
132
175
|
BAR = "━" * 55
|
|
133
176
|
|
|
134
177
|
click.echo(f"\n{BAR}")
|
|
135
|
-
click.echo(f" {BOLD}Correctover Runtime Guard{RESET}
|
|
178
|
+
click.echo(f" {BOLD}Correctover Runtime Guard{RESET} [PRO]")
|
|
136
179
|
click.echo(f" Transport: {BOLD}{transport}{RESET}")
|
|
137
180
|
click.echo(f" Detection: {GREEN}{LATENCY_P50} P50{RESET}")
|
|
138
181
|
click.echo(f" Patterns: {len(FAULT_PATTERNS)} cross-referenced with CCS v2.5 taxonomy")
|
|
139
|
-
click.echo(f" {DIM}Backed by 52 ZDI bounty cases ·
|
|
140
|
-
if not is_pro:
|
|
141
|
-
click.echo(f"\n ⚠️ Free mode: diagnosis only, no live interception.")
|
|
142
|
-
click.echo(f" Pro required for real-time blocking + auto-heal.")
|
|
182
|
+
click.echo(f" {DIM}Backed by 52 ZDI bounty cases · 5 verified PoCs · 3 CVEs{RESET}")
|
|
143
183
|
click.echo(f"{BAR}\n")
|
|
144
184
|
|
|
145
|
-
if not is_pro:
|
|
146
|
-
click.echo(f" Running in diagnose-only mode.")
|
|
147
|
-
click.echo(f" Threats will be detected but NOT blocked.\n")
|
|
148
|
-
click.echo(f" 🛡️ Upgrade for real-time blocking: {CTA_URL}\n")
|
|
149
|
-
|
|
150
185
|
from .mcp_server import serve
|
|
151
186
|
serve(transport=transport, host=host, port=port)
|
|
152
187
|
|
|
@@ -154,53 +189,51 @@ def start(transport, host, port):
|
|
|
154
189
|
@cli.command()
|
|
155
190
|
@click.argument("error_message")
|
|
156
191
|
def diagnose(error_message):
|
|
157
|
-
"""Diagnose an error message for fault patterns.
|
|
158
|
-
|
|
192
|
+
"""Diagnose an error message for fault patterns.
|
|
193
|
+
|
|
194
|
+
Free tier: shows first 2 threats (no repair strategies).
|
|
195
|
+
Pro tier: shows all threats with full repair + evidence.
|
|
196
|
+
"""
|
|
197
|
+
is_pro, validator = _get_license_status()
|
|
198
|
+
_gate_scan(validator, is_pro)
|
|
159
199
|
|
|
160
200
|
RED = "\033[91m"; YELLOW = "\033[93m"; GREEN = "\033[92m"
|
|
161
201
|
CYAN = "\033[96m"; BOLD = "\033[1m"; DIM = "\033[2m"; RESET = "\033[0m"
|
|
162
202
|
BAR = "━" * 55
|
|
163
203
|
|
|
164
|
-
guard
|
|
204
|
+
# Create guard with license awareness
|
|
205
|
+
guard = RuntimeGuard(require_license=False)
|
|
206
|
+
if is_pro:
|
|
207
|
+
guard._free_mode = False
|
|
208
|
+
guard._is_pro = True
|
|
209
|
+
else:
|
|
210
|
+
guard._free_mode = True
|
|
211
|
+
guard._is_pro = False
|
|
212
|
+
|
|
165
213
|
events = guard.diagnose_error(error_message)
|
|
214
|
+
validator.record_scan(risks_found=len(events))
|
|
166
215
|
|
|
167
216
|
click.echo(f"\n{BAR}")
|
|
168
217
|
click.echo(f" {BOLD}Error Diagnosis Report{RESET}")
|
|
169
218
|
click.echo(f" Input: {DIM}{error_message[:120]}{'...' if len(error_message) > 120 else ''}{RESET}")
|
|
170
|
-
click.echo(f" {DIM}Cross-referenced with CCS v2.5 taxonomy (52 ZDI cases,
|
|
219
|
+
click.echo(f" {DIM}Cross-referenced with CCS v2.5 taxonomy (52 ZDI cases, 5 verified PoCs){RESET}")
|
|
171
220
|
click.echo(f"{BAR}\n")
|
|
172
221
|
|
|
173
222
|
if not events:
|
|
174
223
|
click.echo(f" {GREEN}✅ No fault patterns detected — input appears safe.{RESET}")
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
224
|
+
if not is_pro:
|
|
225
|
+
click.echo(f"\n{BAR}")
|
|
226
|
+
click.echo(f"🛡️ Stay protected with Pro:")
|
|
227
|
+
click.echo(f" ✓ Real-time blocking (not just diagnosis)")
|
|
228
|
+
click.echo(f" ✓ Auto-heal on detected threats")
|
|
229
|
+
click.echo(f" ✓ Compliance audit trail")
|
|
230
|
+
click.echo(f"{BAR}")
|
|
231
|
+
click.echo(f" → {CTA_URL}")
|
|
232
|
+
click.echo(f"{BAR}\n")
|
|
183
233
|
return
|
|
184
234
|
|
|
185
235
|
total = len(events)
|
|
186
236
|
|
|
187
|
-
# Ammunition summary
|
|
188
|
-
verified_count = sum(1 for e in events if _get_ammo(e.pattern.pattern_id).get("verified_poc"))
|
|
189
|
-
bounty_count = sum(1 for e in events if _get_ammo(e.pattern.pattern_id).get("bounty_cases"))
|
|
190
|
-
cve_events = [e for e in events if _get_ammo(e.pattern.pattern_id).get("cve")]
|
|
191
|
-
|
|
192
|
-
click.echo(f" {RED}{BOLD}🚨 {total} threat pattern(s) detected{RESET}\n")
|
|
193
|
-
|
|
194
|
-
if verified_count > 0 or bounty_count > 0 or cve_events:
|
|
195
|
-
if verified_count > 0:
|
|
196
|
-
click.echo(f" {RED}{BOLD}⚠ {verified_count} pattern(s) match verified PoC exploits{RESET}")
|
|
197
|
-
if bounty_count > 0:
|
|
198
|
-
click.echo(f" {RED}{BOLD}⚠ {bounty_count} pattern(s) backed by real ZDI bounty cases{RESET}")
|
|
199
|
-
if cve_events:
|
|
200
|
-
cves = set(_get_ammo(e.pattern.pattern_id)["cve"] for e in cve_events if _get_ammo(e.pattern.pattern_id).get("cve"))
|
|
201
|
-
click.echo(f" {RED}{BOLD}⚠ CVEs: {', '.join(cves)}{RESET}")
|
|
202
|
-
click.echo()
|
|
203
|
-
|
|
204
237
|
if is_pro:
|
|
205
238
|
# Pro: show all with repair and evidence
|
|
206
239
|
for i, e in enumerate(events, 1):
|
|
@@ -212,7 +245,10 @@ def diagnose(error_message):
|
|
|
212
245
|
if ammo:
|
|
213
246
|
evidence_parts = [ammo["cwe"]]
|
|
214
247
|
if ammo.get("cve"):
|
|
215
|
-
|
|
248
|
+
if ammo.get("cvss"):
|
|
249
|
+
evidence_parts.append(f"{ammo['cve']} (CVSS {ammo['cvss']})")
|
|
250
|
+
else:
|
|
251
|
+
evidence_parts.append(f"{ammo['cve']} (CVSS unverified)")
|
|
216
252
|
click.echo(f" {CYAN}📎 Maps to: {' | '.join(evidence_parts)}{RESET}")
|
|
217
253
|
if ammo.get("real_target"):
|
|
218
254
|
click.echo(f" {DIM} Exploited in: {ammo['real_target']}{RESET}")
|
|
@@ -224,9 +260,9 @@ def diagnose(error_message):
|
|
|
224
260
|
click.echo(f"{BAR}\n")
|
|
225
261
|
return
|
|
226
262
|
|
|
227
|
-
# Free: show first
|
|
263
|
+
# Free: show first 2 without repair, hint at hidden ones
|
|
228
264
|
shown = events[:FREE_THREAT_PREVIEW]
|
|
229
|
-
|
|
265
|
+
hidden_count = total - FREE_THREAT_PREVIEW
|
|
230
266
|
|
|
231
267
|
for i, e in enumerate(shown, 1):
|
|
232
268
|
sev_color = RED if e.pattern.severity == "CRITICAL" else YELLOW
|
|
@@ -237,7 +273,10 @@ def diagnose(error_message):
|
|
|
237
273
|
if ammo:
|
|
238
274
|
evidence_parts = [ammo["cwe"]]
|
|
239
275
|
if ammo.get("cve"):
|
|
240
|
-
|
|
276
|
+
if ammo.get("cvss"):
|
|
277
|
+
evidence_parts.append(f"{ammo['cve']} (CVSS {ammo['cvss']})")
|
|
278
|
+
else:
|
|
279
|
+
evidence_parts.append(f"{ammo['cve']} (CVSS unverified)")
|
|
241
280
|
click.echo(f" {CYAN}📎 Evidence: {' | '.join(evidence_parts)}{RESET}")
|
|
242
281
|
if ammo.get("real_target"):
|
|
243
282
|
click.echo(f" {DIM} Exploited in: {ammo['real_target']}{RESET}")
|
|
@@ -247,43 +286,30 @@ def diagnose(error_message):
|
|
|
247
286
|
|
|
248
287
|
click.echo(f" 🔒 Repair strategy — Pro only\n")
|
|
249
288
|
|
|
250
|
-
if
|
|
251
|
-
hidden_events = events[FREE_THREAT_PREVIEW:]
|
|
252
|
-
hidden_verified = sum(1 for e in hidden_events if _get_ammo(e.pattern.pattern_id).get("verified_poc"))
|
|
253
|
-
hidden_cves = set(_get_ammo(e.pattern.pattern_id).get("cve") for e in hidden_events if _get_ammo(e.pattern.pattern_id).get("cve"))
|
|
254
|
-
hidden_critical = sum(1 for e in hidden_events if e.pattern.severity == "CRITICAL")
|
|
255
|
-
|
|
289
|
+
if hidden_count > 0:
|
|
256
290
|
click.echo(f" {'─' * 51}")
|
|
257
|
-
click.echo(f" 🔒 {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
f" ✓ Real-time blocking ({LATENCY_P50} P50)\n"
|
|
274
|
-
f" ✓ Auto-heal (84.1% resolved automatically)\n"
|
|
275
|
-
f" ✓ Live interception MCP server\n"
|
|
276
|
-
f"{BAR}\n"
|
|
277
|
-
f" → {CTA_URL}\n"
|
|
278
|
-
f" → export CORRECTOVER_LICENSE_KEY=<your-key>\n"
|
|
279
|
-
f"{BAR}\n"
|
|
280
|
-
)
|
|
291
|
+
click.echo(f" 🔒 {hidden_count} additional threat(s) hidden.")
|
|
292
|
+
click.echo(f"\n{BAR}")
|
|
293
|
+
click.echo(
|
|
294
|
+
f"\n{BAR}\n"
|
|
295
|
+
f"🛡️ UPGRADE TO PRO TO UNLOCK:\n"
|
|
296
|
+
f" ✓ All {total} threat(s) ({hidden_count} hidden)\n"
|
|
297
|
+
f" ✓ Repair strategies for each threat\n"
|
|
298
|
+
f" ✓ Full ZDI bounty case details\n"
|
|
299
|
+
f" ✓ Real-time blocking ({LATENCY_P50} P50)\n"
|
|
300
|
+
f" ✓ Auto-heal on detected threats\n"
|
|
301
|
+
f" ✓ Live interception MCP server\n"
|
|
302
|
+
f"{BAR}\n"
|
|
303
|
+
f" → {CTA_URL}\n"
|
|
304
|
+
f" → export CORRECTOVER_LICENSE_KEY=<your-key>\n"
|
|
305
|
+
f"{BAR}\n"
|
|
306
|
+
)
|
|
281
307
|
|
|
282
308
|
|
|
283
309
|
@cli.command()
|
|
284
310
|
def stats():
|
|
285
311
|
"""Show guard statistics and registered patterns."""
|
|
286
|
-
is_pro, validator =
|
|
312
|
+
is_pro, validator = _get_license_status()
|
|
287
313
|
|
|
288
314
|
GREEN = "\033[92m"; RED = "\033[91m"; CYAN = "\033[96m"
|
|
289
315
|
BOLD = "\033[1m"; DIM = "\033[2m"; RESET = "\033[0m"
|
|
@@ -293,7 +319,7 @@ def stats():
|
|
|
293
319
|
click.echo(f" {BOLD}Runtime Guard Statistics{RESET}")
|
|
294
320
|
click.echo(f" Detection latency: {GREEN}{LATENCY_P50} P50{RESET}")
|
|
295
321
|
click.echo(f" Fault patterns: {len(FAULT_PATTERNS)} cross-referenced with CCS v2.5")
|
|
296
|
-
click.echo(f" {DIM}Backed by 52 ZDI bounty cases ·
|
|
322
|
+
click.echo(f" {DIM}Backed by 52 ZDI bounty cases · 5 verified PoCs · 3 CVEs · max CVSS 9.8{RESET}")
|
|
297
323
|
click.echo(f"{BAR}\n")
|
|
298
324
|
|
|
299
325
|
from collections import Counter
|
|
@@ -309,7 +335,11 @@ def stats():
|
|
|
309
335
|
ammo = _get_ammo(p.pattern_id)
|
|
310
336
|
click.echo(f" {sev_color}[{p.severity}]{RESET} {DIM}[{p.pattern_id}]{RESET} {p.description}")
|
|
311
337
|
if ammo:
|
|
312
|
-
|
|
338
|
+
if ammo.get("cve"):
|
|
339
|
+
cve_str = (f" | {ammo['cve']} (CVSS {ammo['cvss']})" if ammo.get("cvss")
|
|
340
|
+
else f" | {ammo['cve']} (CVSS unverified)")
|
|
341
|
+
else:
|
|
342
|
+
cve_str = ""
|
|
313
343
|
click.echo(f" {CYAN}📎 {ammo['cwe']}{cve_str}{RESET}")
|
|
314
344
|
if ammo.get("real_target"):
|
|
315
345
|
click.echo(f" {DIM} Exploited in: {ammo['real_target']}{RESET}")
|
|
@@ -334,5 +364,33 @@ def stats():
|
|
|
334
364
|
click.echo(f"\n{BAR}\n")
|
|
335
365
|
|
|
336
366
|
|
|
367
|
+
@cli.command()
|
|
368
|
+
def activate():
|
|
369
|
+
"""Activate a Pro license key.
|
|
370
|
+
|
|
371
|
+
Usage: correctover activate <license-key>
|
|
372
|
+
Or: export CORRECTOVER_LICENSE_KEY=<key>
|
|
373
|
+
"""
|
|
374
|
+
is_pro, validator = _get_license_status()
|
|
375
|
+
GREEN = "\033[92m"; RED = "\033[91m"; BOLD = "\033[1m"; RESET = "\033[0m"
|
|
376
|
+
BAR = "━" * 55
|
|
377
|
+
|
|
378
|
+
if is_pro:
|
|
379
|
+
click.echo(f"\n{BAR}")
|
|
380
|
+
click.echo(f" {GREEN}✅ Pro license active.{RESET}")
|
|
381
|
+
click.echo(f" Key: {validator.state.get('license_key', 'N/A')[:12]}...")
|
|
382
|
+
click.echo(f"{BAR}\n")
|
|
383
|
+
return
|
|
384
|
+
|
|
385
|
+
click.echo(f"\n{BAR}")
|
|
386
|
+
click.echo(f" {RED}No valid Pro license found.{RESET}")
|
|
387
|
+
click.echo(f"")
|
|
388
|
+
click.echo(f" To activate:")
|
|
389
|
+
click.echo(f" 1. Purchase at {CTA_URL}")
|
|
390
|
+
click.echo(f" 2. export CORRECTOVER_LICENSE_KEY=<your-key>")
|
|
391
|
+
click.echo(f" 3. Run: correctover activate")
|
|
392
|
+
click.echo(f"{BAR}\n")
|
|
393
|
+
|
|
394
|
+
|
|
337
395
|
if __name__ == "__main__":
|
|
338
396
|
cli()
|