correctover-scan 1.1.0 → 1.2.1
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 +128 -0
- package/index.js +18 -3
- package/package.json +3 -2
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
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License validator for correctover-scan NPM.
|
|
3
|
+
* Mirrors the Python LicenseValidator: 50 free scans/day, CORRECTOVER_LICENSE_KEY unlocks.
|
|
4
|
+
* Supports CV-TRL/CV-PRO (FC) and COV- (Cloud) key formats.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const crypto = require('crypto');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
const FREE_LIMIT_PER_DAY = 50;
|
|
13
|
+
const STATE_FILE = path.join(os.homedir(), '.correctover', 'license.json');
|
|
14
|
+
|
|
15
|
+
function loadState() {
|
|
16
|
+
try {
|
|
17
|
+
if (fs.existsSync(STATE_FILE)) {
|
|
18
|
+
return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
|
|
19
|
+
}
|
|
20
|
+
} catch (e) {}
|
|
21
|
+
return { products: {}, license_key: null, installed_at: Date.now() / 1000 };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function saveState(state) {
|
|
25
|
+
try {
|
|
26
|
+
fs.mkdirSync(path.dirname(STATE_FILE), { recursive: true });
|
|
27
|
+
fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
|
|
28
|
+
} catch (e) {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getProductState(state, product) {
|
|
32
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
33
|
+
if (!state.products[product]) {
|
|
34
|
+
state.products[product] = { calls_today: 0, date: today, total_calls: 0 };
|
|
35
|
+
}
|
|
36
|
+
if (state.products[product].date !== today) {
|
|
37
|
+
state.products[product].calls_today = 0;
|
|
38
|
+
state.products[product].date = today;
|
|
39
|
+
}
|
|
40
|
+
return state.products[product];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function verifyLicenseKey(key) {
|
|
44
|
+
if (!key || key.length < 12) return false;
|
|
45
|
+
|
|
46
|
+
// COV-<product>-<hash> (Cloud HMAC)
|
|
47
|
+
if (key.startsWith('COV-')) {
|
|
48
|
+
const parts = key.split('-');
|
|
49
|
+
if (parts.length < 3) return false;
|
|
50
|
+
const productCode = parts.slice(1, -1).join('-');
|
|
51
|
+
const secret = `correctover-${productCode}-2026`;
|
|
52
|
+
const expected = crypto.createHash('sha256').update(secret).digest('hex').slice(0, 12);
|
|
53
|
+
return parts[parts.length - 1].startsWith(expected);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// CV-TRL-<base64> / CV-PRO-<base64> (FC XunhuPay)
|
|
57
|
+
if (key.startsWith('CV-')) {
|
|
58
|
+
const parts = key.split('-', 2);
|
|
59
|
+
if (parts.length < 3) return false;
|
|
60
|
+
try {
|
|
61
|
+
let payload = parts[2];
|
|
62
|
+
const dot = payload.indexOf('.');
|
|
63
|
+
if (dot > 0) payload = payload.substring(0, dot);
|
|
64
|
+
const decoded = Buffer.from(payload, 'base64url').toString();
|
|
65
|
+
return decoded.includes('@') || decoded.length > 10;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function checkLicense(product) {
|
|
75
|
+
const state = loadState();
|
|
76
|
+
const ps = getProductState(state, product);
|
|
77
|
+
const licenseKey = state.license_key || process.env.CORRECTOVER_LICENSE_KEY;
|
|
78
|
+
|
|
79
|
+
if (licenseKey && verifyLicenseKey(licenseKey)) {
|
|
80
|
+
return {
|
|
81
|
+
authorized: true,
|
|
82
|
+
tier: 'pro',
|
|
83
|
+
calls_remaining: Infinity,
|
|
84
|
+
calls_today: ps.calls_today,
|
|
85
|
+
limit: Infinity,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const remaining = Math.max(0, FREE_LIMIT_PER_DAY - ps.calls_today);
|
|
90
|
+
return {
|
|
91
|
+
authorized: remaining > 0,
|
|
92
|
+
tier: 'free',
|
|
93
|
+
calls_remaining: remaining,
|
|
94
|
+
calls_today: ps.calls_today,
|
|
95
|
+
limit: FREE_LIMIT_PER_DAY,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function recordCall(product) {
|
|
100
|
+
const state = loadState();
|
|
101
|
+
const status = checkLicense(product);
|
|
102
|
+
if (!status.authorized) return status;
|
|
103
|
+
|
|
104
|
+
const ps = getProductState(state, product);
|
|
105
|
+
ps.calls_today += 1;
|
|
106
|
+
ps.total_calls = (ps.total_calls || 0) + 1;
|
|
107
|
+
saveState(state);
|
|
108
|
+
|
|
109
|
+
status.calls_remaining = Math.max(0, status.limit - ps.calls_today);
|
|
110
|
+
status.calls_today = ps.calls_today;
|
|
111
|
+
return status;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getUpgradeMessage(status) {
|
|
115
|
+
if (status.tier !== 'free') return '';
|
|
116
|
+
if (status.calls_remaining <= 0) {
|
|
117
|
+
return `\n🚫 Free tier limit reached (${FREE_LIMIT_PER_DAY} scans/day).\n Upgrade: https://correctover.com/checkout\n Or: export CORRECTOVER_LICENSE_KEY=<your-key>\n`;
|
|
118
|
+
}
|
|
119
|
+
return `\n📊 Free tier: ${status.calls_remaining} scans remaining today.\n Upgrade: https://correctover.com/checkout\n`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = {
|
|
123
|
+
FREE_LIMIT_PER_DAY,
|
|
124
|
+
checkLicense,
|
|
125
|
+
recordCall,
|
|
126
|
+
getUpgradeMessage,
|
|
127
|
+
verifyLicenseKey,
|
|
128
|
+
};
|
package/index.js
CHANGED
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const { runScan, parseConfig, KNOWN_CONFIG_PATHS } = require('./core/scanner');
|
|
13
|
+
const { recordCall, getUpgradeMessage } = require('./core/license');
|
|
13
14
|
|
|
14
|
-
const VERSION = '1.
|
|
15
|
+
const VERSION = '1.2.0';
|
|
16
|
+
const PRODUCT = 'correctover-scan';
|
|
15
17
|
|
|
16
18
|
// Colors
|
|
17
19
|
const c = {
|
|
@@ -112,11 +114,11 @@ function formatResults(results, stats, filename) {
|
|
|
112
114
|
if (stats.fail > 0 || stats.score < 60) {
|
|
113
115
|
lines.push(`${c.yellow}${c.bold}⚡ Score too low? CCS Pro generates formal compliance reports.${c.reset}`);
|
|
114
116
|
lines.push(`${c.dim} Enterprise: real-time runtime protection + Token guarantee${c.reset}`);
|
|
115
|
-
lines.push(`${c.cyan} →
|
|
117
|
+
lines.push(`${c.cyan} → Upgrade: https://correctover.com/checkout${c.reset}`);
|
|
116
118
|
} else {
|
|
117
119
|
lines.push(`${c.green}✓ Good score! Get a formal compliance certificate with CCS Pro.${c.reset}`);
|
|
118
120
|
lines.push(`${c.dim} Audit reports · Team dashboard · Custom rules · SOC 2 ready${c.reset}`);
|
|
119
|
-
lines.push(`${c.cyan} → https://correctover.com/
|
|
121
|
+
lines.push(`${c.cyan} → https://correctover.com/checkout${c.reset}`);
|
|
120
122
|
}
|
|
121
123
|
lines.push(`${c.dim}Enterprise: runtime SDK + Token guarantee → https://correctover.com${c.reset}`);
|
|
122
124
|
lines.push('');
|
|
@@ -204,6 +206,19 @@ Examples:
|
|
|
204
206
|
|
|
205
207
|
printBanner();
|
|
206
208
|
|
|
209
|
+
// License check
|
|
210
|
+
const status = recordCall(PRODUCT);
|
|
211
|
+
if (!status.authorized) {
|
|
212
|
+
console.log(getUpgradeMessage(status));
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
if (status.tier === 'free') {
|
|
216
|
+
console.log(`${c.dim}📊 Free tier: ${status.calls_remaining} scans remaining today (${status.calls_today}/${status.limit})${c.reset}`);
|
|
217
|
+
console.log(`${c.dim} Upgrade: https://correctover.com/checkout${c.reset}\n`);
|
|
218
|
+
} else if (status.tier === 'pro') {
|
|
219
|
+
console.log(`${c.green}✅ Pro license active — unlimited scans${c.reset}\n`);
|
|
220
|
+
}
|
|
221
|
+
|
|
207
222
|
const filesToScan = [];
|
|
208
223
|
|
|
209
224
|
if (configPath) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "correctover-scan",
|
|
3
|
-
"version": "1.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "MCP security scanner — 1 command, 14 OWASP AISVS 1.0 checks. Detect RCE, SSRF, credential exposure in your Model Context Protocol configs. Free: 50 scans/day.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"correctover-scan": "./index.js"
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"files": [
|
|
40
40
|
"index.js",
|
|
41
41
|
"core/scanner.js",
|
|
42
|
+
"core/license.js",
|
|
42
43
|
"README.md"
|
|
43
44
|
],
|
|
44
45
|
"engines": {
|