correctover-scan 1.3.0 → 1.5.0
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.
- package/README.md +22 -1
- package/core/license.js +75 -40
- package/package.json +4 -9
package/README.md
CHANGED
|
@@ -82,10 +82,31 @@ Try the online version: [correctover.com/scan](https://correctover.com/scan/)
|
|
|
82
82
|
- **OWASP AISVS 1.0** — AI System Vulnerability Severity
|
|
83
83
|
- **GB/T《智能体应用安全基本要求》** — Chinese National Mandatory Standard
|
|
84
84
|
|
|
85
|
+
## Free Tier
|
|
86
|
+
|
|
87
|
+
50 scans/day — no credit card required.
|
|
88
|
+
|
|
89
|
+
Unlock unlimited: [correctover.com/checkout](https://correctover.com/checkout)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
export CORRECTOVER_LICENSE_KEY=your-key-here
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Related Correctover Tools
|
|
96
|
+
|
|
97
|
+
| Tool | Install | Description |
|
|
98
|
+
|------|---------|-------------|
|
|
99
|
+
| **Security Scanner** | `npx correctover-scan` | MCP config security audit (14 checks) |
|
|
100
|
+
| **Self-Healing Test** | `pip install correctover-test` | Agent self-healing test suite |
|
|
101
|
+
| **Vulnerability Scan** | `pip install correctover-security-audit` | 215 fault type scanner |
|
|
102
|
+
| **Compliance Check** | `pip install correctover-compliance-check` | OAuth 2.1 + CCS v1.0 |
|
|
103
|
+
| **Runtime Guard** | `pip install correctover-runtime-guard` | 22µs RCE/SSRF interception |
|
|
104
|
+
| **MCP Server** | `npm install correctover-mcp-server` | 6-dimension validation |
|
|
105
|
+
|
|
85
106
|
## Links
|
|
86
107
|
|
|
87
108
|
- [correctover.com](https://correctover.com) — AI Agent Runtime Assurance
|
|
88
|
-
- [CCS Standard](https://correctover.com/ccs) — Conformance Specification
|
|
109
|
+
- [CCS Standard](https://correctover.com/ccs) — Conformance Specification (DOI: 10.5281/zenodo.21234580)
|
|
89
110
|
- [Web Scanner](https://correctover.com/scan/) — Online version
|
|
90
111
|
- [GitHub](https://github.com/Correctover) — Source code
|
|
91
112
|
|
package/core/license.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* License validator
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* License validator — freemium hook model.
|
|
3
|
+
*
|
|
4
|
+
* Free: unlimited scanning (see all risks)
|
|
5
|
+
* Pro: fix recommendations, auto-heal, reports, history
|
|
6
|
+
*
|
|
7
|
+
* The hook: users see ALL their problems for free.
|
|
8
|
+
* The paywall: solutions are locked.
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
11
|
const fs = require('fs');
|
|
@@ -9,8 +13,8 @@ const path = require('path');
|
|
|
9
13
|
const crypto = require('crypto');
|
|
10
14
|
const os = require('os');
|
|
11
15
|
|
|
12
|
-
const FREE_LIMIT_PER_DAY = 50;
|
|
13
16
|
const STATE_FILE = path.join(os.homedir(), '.correctover', 'license.json');
|
|
17
|
+
const FREE_FIX_PREVIEW = 2;
|
|
14
18
|
|
|
15
19
|
function loadState() {
|
|
16
20
|
try {
|
|
@@ -18,7 +22,7 @@ function loadState() {
|
|
|
18
22
|
return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
|
|
19
23
|
}
|
|
20
24
|
} catch (e) {}
|
|
21
|
-
return { products: {}, license_key: null, installed_at: Date.now() / 1000 };
|
|
25
|
+
return { products: {}, license_key: null, installed_at: Date.now() / 1000, scan_history: [] };
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
function saveState(state) {
|
|
@@ -29,13 +33,8 @@ function saveState(state) {
|
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
function getProductState(state, product) {
|
|
32
|
-
const today = new Date().toISOString().slice(0, 10);
|
|
33
36
|
if (!state.products[product]) {
|
|
34
|
-
state.products[product] = {
|
|
35
|
-
}
|
|
36
|
-
if (state.products[product].date !== today) {
|
|
37
|
-
state.products[product].calls_today = 0;
|
|
38
|
-
state.products[product].date = today;
|
|
37
|
+
state.products[product] = { total_scans: 0, total_risks_found: 0, first_scan: Date.now()/1000, last_scan: null };
|
|
39
38
|
}
|
|
40
39
|
return state.products[product];
|
|
41
40
|
}
|
|
@@ -43,7 +42,6 @@ function getProductState(state, product) {
|
|
|
43
42
|
function verifyLicenseKey(key) {
|
|
44
43
|
if (!key || key.length < 12) return false;
|
|
45
44
|
|
|
46
|
-
// COV-<product>-<hash> (Cloud HMAC)
|
|
47
45
|
if (key.startsWith('COV-')) {
|
|
48
46
|
const parts = key.split('-');
|
|
49
47
|
if (parts.length < 3) return false;
|
|
@@ -53,7 +51,6 @@ function verifyLicenseKey(key) {
|
|
|
53
51
|
return parts[parts.length - 1].startsWith(expected);
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
// CV-TRL-<base64> / CV-PRO-<base64> (FC XunhuPay)
|
|
57
54
|
if (key.startsWith('CV-')) {
|
|
58
55
|
const parts = key.split('-', 2);
|
|
59
56
|
if (parts.length < 3) return false;
|
|
@@ -73,56 +70,94 @@ function verifyLicenseKey(key) {
|
|
|
73
70
|
|
|
74
71
|
function checkLicense(product) {
|
|
75
72
|
const state = loadState();
|
|
76
|
-
const ps = getProductState(state, product);
|
|
77
73
|
const licenseKey = state.license_key || process.env.CORRECTOVER_LICENSE_KEY;
|
|
78
74
|
|
|
79
75
|
if (licenseKey && verifyLicenseKey(licenseKey)) {
|
|
80
76
|
return {
|
|
81
|
-
authorized: true,
|
|
82
77
|
tier: 'pro',
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
can_scan: true,
|
|
79
|
+
can_fix: true,
|
|
80
|
+
can_report: true,
|
|
81
|
+
can_heal: true,
|
|
82
|
+
can_history: true,
|
|
83
|
+
fix_preview: Infinity,
|
|
86
84
|
};
|
|
87
85
|
}
|
|
88
86
|
|
|
89
|
-
const remaining = Math.max(0, FREE_LIMIT_PER_DAY - ps.calls_today);
|
|
90
87
|
return {
|
|
91
|
-
authorized: remaining > 0,
|
|
92
88
|
tier: 'free',
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
can_scan: true,
|
|
90
|
+
can_fix: false,
|
|
91
|
+
can_report: false,
|
|
92
|
+
can_heal: false,
|
|
93
|
+
can_history: false,
|
|
94
|
+
fix_preview: FREE_FIX_PREVIEW,
|
|
96
95
|
};
|
|
97
96
|
}
|
|
98
97
|
|
|
99
|
-
function
|
|
98
|
+
function recordScan(product, risksFound) {
|
|
100
99
|
const state = loadState();
|
|
100
|
+
const ps = getProductState(state, product);
|
|
101
|
+
ps.total_scans += 1;
|
|
102
|
+
ps.total_risks_found += risksFound || 0;
|
|
103
|
+
ps.last_scan = Date.now() / 1000;
|
|
104
|
+
|
|
105
|
+
const history = state.scan_history || [];
|
|
106
|
+
history.push({ time: Date.now()/1000, product, risks: risksFound || 0 });
|
|
107
|
+
|
|
101
108
|
const status = checkLicense(product);
|
|
102
|
-
if (
|
|
109
|
+
if (status.tier === 'free' && history.length > 1) {
|
|
110
|
+
state.scan_history = history.slice(-1);
|
|
111
|
+
} else {
|
|
112
|
+
state.scan_history = history;
|
|
113
|
+
}
|
|
103
114
|
|
|
104
|
-
const ps = getProductState(state, product);
|
|
105
|
-
ps.calls_today += 1;
|
|
106
|
-
ps.total_calls = (ps.total_calls || 0) + 1;
|
|
107
115
|
saveState(state);
|
|
116
|
+
return checkLicense(product);
|
|
117
|
+
}
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
119
|
+
function getFixCTA(totalRisks, hiddenRisks) {
|
|
120
|
+
if (hiddenRisks <= 0) return '';
|
|
121
|
+
const shown = totalRisks - hiddenRisks;
|
|
122
|
+
return [
|
|
123
|
+
'',
|
|
124
|
+
'━'.repeat(55),
|
|
125
|
+
`🔒 ${hiddenRisks} fix recommendation(s) locked.`,
|
|
126
|
+
` You have ${totalRisks} risk(s) but can only see ${shown} fix(es).`,
|
|
127
|
+
'',
|
|
128
|
+
'🛡️ Upgrade to Pro to unlock:',
|
|
129
|
+
` ✓ Fix recommendations for all ${totalRisks} risk(s)`,
|
|
130
|
+
' ✓ Auto-heal (84.1% issues resolved automatically)',
|
|
131
|
+
' ✓ HTML/PDF audit reports',
|
|
132
|
+
' ✓ Scan history & tracking',
|
|
133
|
+
'━'.repeat(55),
|
|
134
|
+
' → https://correctover.com/checkout',
|
|
135
|
+
' → export CORRECTOVER_LICENSE_KEY=<your-key>',
|
|
136
|
+
'━'.repeat(55),
|
|
137
|
+
].join('\n');
|
|
112
138
|
}
|
|
113
139
|
|
|
114
|
-
function
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
140
|
+
function getNoRiskCTA() {
|
|
141
|
+
return [
|
|
142
|
+
'',
|
|
143
|
+
'━'.repeat(55),
|
|
144
|
+
'✅ No risks found in this scan.',
|
|
145
|
+
'',
|
|
146
|
+
'🛡️ Stay protected with Pro:',
|
|
147
|
+
' ✓ Continuous monitoring (auto-scan on changes)',
|
|
148
|
+
' ✓ Auto-heal when risks appear',
|
|
149
|
+
' ✓ Compliance reports (OAuth 2.1, CCS v1.0)',
|
|
150
|
+
'━'.repeat(55),
|
|
151
|
+
' → https://correctover.com/checkout',
|
|
152
|
+
'━'.repeat(55),
|
|
153
|
+
].join('\n');
|
|
120
154
|
}
|
|
121
155
|
|
|
122
156
|
module.exports = {
|
|
123
|
-
|
|
157
|
+
FREE_FIX_PREVIEW,
|
|
124
158
|
checkLicense,
|
|
125
|
-
|
|
126
|
-
getUpgradeMessage,
|
|
159
|
+
recordScan,
|
|
127
160
|
verifyLicenseKey,
|
|
161
|
+
getFixCTA,
|
|
162
|
+
getNoRiskCTA,
|
|
128
163
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "correctover-scan",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "MCP security scanner — 1 command, 14 OWASP AISVS 1.0 checks. Detect RCE, SSRF, credential exposure. Free: 30 checks/month.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"correctover-scan": "./index.js"
|
|
@@ -24,12 +24,7 @@
|
|
|
24
24
|
"cursor",
|
|
25
25
|
"model-context-protocol",
|
|
26
26
|
"vulnerability",
|
|
27
|
-
"audit"
|
|
28
|
-
"runtime-security",
|
|
29
|
-
"rce-detection",
|
|
30
|
-
"ssrf-detection",
|
|
31
|
-
"credential-hijacking",
|
|
32
|
-
"guardrail"
|
|
27
|
+
"audit"
|
|
33
28
|
],
|
|
34
29
|
"author": "Correctover",
|
|
35
30
|
"license": "MIT",
|
|
@@ -50,4 +45,4 @@
|
|
|
50
45
|
"engines": {
|
|
51
46
|
"node": ">=16.0.0"
|
|
52
47
|
}
|
|
53
|
-
}
|
|
48
|
+
}
|