project-shield 1.0.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 +440 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +151 -0
- package/dist/index.js.map +1 -0
- package/dist/integrity/failsafe.d.ts +17 -0
- package/dist/integrity/failsafe.d.ts.map +1 -0
- package/dist/integrity/failsafe.js +45 -0
- package/dist/integrity/failsafe.js.map +1 -0
- package/dist/integrity/ruleset.d.ts +12 -0
- package/dist/integrity/ruleset.d.ts.map +1 -0
- package/dist/integrity/ruleset.js +77 -0
- package/dist/integrity/ruleset.js.map +1 -0
- package/dist/integrity/seal.d.ts +12 -0
- package/dist/integrity/seal.d.ts.map +1 -0
- package/dist/integrity/seal.js +77 -0
- package/dist/integrity/seal.js.map +1 -0
- package/dist/output/badge.d.ts +16 -0
- package/dist/output/badge.d.ts.map +1 -0
- package/dist/output/badge.js +112 -0
- package/dist/output/badge.js.map +1 -0
- package/dist/output/evidence.d.ts +18 -0
- package/dist/output/evidence.d.ts.map +1 -0
- package/dist/output/evidence.js +205 -0
- package/dist/output/evidence.js.map +1 -0
- package/dist/output/fixit.d.ts +32 -0
- package/dist/output/fixit.d.ts.map +1 -0
- package/dist/output/fixit.js +387 -0
- package/dist/output/fixit.js.map +1 -0
- package/dist/output/terminal.d.ts +10 -0
- package/dist/output/terminal.d.ts.map +1 -0
- package/dist/output/terminal.js +190 -0
- package/dist/output/terminal.js.map +1 -0
- package/dist/scanner/engine.d.ts +6 -0
- package/dist/scanner/engine.d.ts.map +1 -0
- package/dist/scanner/engine.js +155 -0
- package/dist/scanner/engine.js.map +1 -0
- package/dist/scanner/ignore.d.ts +20 -0
- package/dist/scanner/ignore.d.ts.map +1 -0
- package/dist/scanner/ignore.js +125 -0
- package/dist/scanner/ignore.js.map +1 -0
- package/dist/scanner/injection.d.ts +15 -0
- package/dist/scanner/injection.d.ts.map +1 -0
- package/dist/scanner/injection.js +234 -0
- package/dist/scanner/injection.js.map +1 -0
- package/dist/scanner/mcp.d.ts +6 -0
- package/dist/scanner/mcp.d.ts.map +1 -0
- package/dist/scanner/mcp.js +322 -0
- package/dist/scanner/mcp.js.map +1 -0
- package/dist/scanner/pii.d.ts +21 -0
- package/dist/scanner/pii.d.ts.map +1 -0
- package/dist/scanner/pii.js +161 -0
- package/dist/scanner/pii.js.map +1 -0
- package/dist/scanner/secrets.d.ts +10 -0
- package/dist/scanner/secrets.d.ts.map +1 -0
- package/dist/scanner/secrets.js +224 -0
- package/dist/scanner/secrets.js.map +1 -0
- package/dist/scoring/lock.d.ts +12 -0
- package/dist/scoring/lock.d.ts.map +1 -0
- package/dist/scoring/lock.js +58 -0
- package/dist/scoring/lock.js.map +1 -0
- package/dist/scoring/score.d.ts +14 -0
- package/dist/scoring/score.d.ts.map +1 -0
- package/dist/scoring/score.js +74 -0
- package/dist/scoring/score.js.map +1 -0
- package/dist/types/index.d.ts +205 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +52 -0
- package/rules/v1.0.0.json +248 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shannonEntropy = shannonEntropy;
|
|
4
|
+
exports.scanFileSecrets = scanFileSecrets;
|
|
5
|
+
const ignore_js_1 = require("./ignore.js");
|
|
6
|
+
/**
|
|
7
|
+
* Calculate Shannon entropy of a string.
|
|
8
|
+
*/
|
|
9
|
+
function shannonEntropy(str) {
|
|
10
|
+
if (str.length === 0)
|
|
11
|
+
return 0;
|
|
12
|
+
const freq = new Map();
|
|
13
|
+
for (const ch of str) {
|
|
14
|
+
freq.set(ch, (freq.get(ch) ?? 0) + 1);
|
|
15
|
+
}
|
|
16
|
+
let entropy = 0;
|
|
17
|
+
const len = str.length;
|
|
18
|
+
for (const count of freq.values()) {
|
|
19
|
+
const p = count / len;
|
|
20
|
+
if (p > 0) {
|
|
21
|
+
entropy -= p * Math.log2(p);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return entropy;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Mask a matched value: show first 4 chars + ****
|
|
28
|
+
*/
|
|
29
|
+
function maskValue(value) {
|
|
30
|
+
if (value.length <= 4)
|
|
31
|
+
return '****';
|
|
32
|
+
return value.substring(0, 4) + '****';
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extract tokens (8+ chars) from a line for entropy analysis.
|
|
36
|
+
*/
|
|
37
|
+
function extractTokens(line) {
|
|
38
|
+
const tokens = [];
|
|
39
|
+
// Split on whitespace, quotes, backticks, and common delimiters
|
|
40
|
+
const regex = /[A-Za-z0-9/+=_-]{8,}/g;
|
|
41
|
+
let match;
|
|
42
|
+
while ((match = regex.exec(line)) !== null) {
|
|
43
|
+
tokens.push({ token: match[0], column: match.index });
|
|
44
|
+
}
|
|
45
|
+
return tokens;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if a line contains context keywords near a value.
|
|
49
|
+
*/
|
|
50
|
+
function hasContextKeywords(line, keywords) {
|
|
51
|
+
const lower = line.toLowerCase();
|
|
52
|
+
return keywords.some(kw => lower.includes(kw.toLowerCase()));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if a file is a .env file.
|
|
56
|
+
*/
|
|
57
|
+
function isEnvFile(filePath) {
|
|
58
|
+
const name = filePath.replace(/\\/g, '/').split('/').pop() ?? '';
|
|
59
|
+
return name === '.env' || name.startsWith('.env.') || name.endsWith('.env');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if the line is an assignment (=, :, =>) with a string literal on the right.
|
|
63
|
+
*/
|
|
64
|
+
function isAssignmentLine(line) {
|
|
65
|
+
return /[=:]/.test(line) || /=>/.test(line);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Layer 1: Regex pattern matching against ruleset patterns.
|
|
69
|
+
*/
|
|
70
|
+
function regexLayer(line, patterns) {
|
|
71
|
+
const hits = [];
|
|
72
|
+
for (const pattern of patterns) {
|
|
73
|
+
const regex = new RegExp(pattern.regex, 'g');
|
|
74
|
+
let match;
|
|
75
|
+
while ((match = regex.exec(line)) !== null) {
|
|
76
|
+
hits.push({ pattern, match });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return hits;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Layer 2: Shannon entropy analysis on tokens.
|
|
83
|
+
*/
|
|
84
|
+
function entropyLayer(line, threshold) {
|
|
85
|
+
const tokens = extractTokens(line);
|
|
86
|
+
return tokens
|
|
87
|
+
.map(t => ({ ...t, entropy: shannonEntropy(t.token) }))
|
|
88
|
+
.filter(t => t.entropy > threshold);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Layer 3: Context check for secret-related variable names.
|
|
92
|
+
*/
|
|
93
|
+
function contextLayer(line, filePath, keywords) {
|
|
94
|
+
// .env files → all values are key candidates
|
|
95
|
+
if (isEnvFile(filePath))
|
|
96
|
+
return true;
|
|
97
|
+
// Check for context keywords
|
|
98
|
+
if (hasContextKeywords(line, keywords))
|
|
99
|
+
return true;
|
|
100
|
+
// Check for assignment with string literal
|
|
101
|
+
if (isAssignmentLine(line) && hasContextKeywords(line, keywords))
|
|
102
|
+
return true;
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Determine severity from layer hits.
|
|
107
|
+
* - 2+ layers hit → critical
|
|
108
|
+
* - 1 layer hit → warning
|
|
109
|
+
* - severity_override takes precedence for certain patterns
|
|
110
|
+
*/
|
|
111
|
+
function determineSeverity(pattern, regexHit, entropyVal, entropyThreshold, contextHit) {
|
|
112
|
+
// Special overrides
|
|
113
|
+
if (pattern?.severity_override) {
|
|
114
|
+
return pattern.severity_override;
|
|
115
|
+
}
|
|
116
|
+
const layerCount = [
|
|
117
|
+
regexHit,
|
|
118
|
+
entropyVal > entropyThreshold,
|
|
119
|
+
contextHit,
|
|
120
|
+
].filter(Boolean).length;
|
|
121
|
+
if (layerCount >= 2)
|
|
122
|
+
return 'critical';
|
|
123
|
+
if (layerCount === 1)
|
|
124
|
+
return 'warning';
|
|
125
|
+
return 'info';
|
|
126
|
+
}
|
|
127
|
+
// Known example/placeholder key patterns that should be downgraded
|
|
128
|
+
const EXAMPLE_KEY_SUFFIXES = ['EXAMPLE', 'TESTING', 'CHANGEME', 'PLACEHOLDER'];
|
|
129
|
+
// Patterns that are too broad to be flagged without context (regex alone is not enough)
|
|
130
|
+
const CONTEXT_REQUIRED_PATTERNS = new Set(['aws_secret_key']);
|
|
131
|
+
/**
|
|
132
|
+
* Check if a matched value looks like a known example/placeholder.
|
|
133
|
+
*/
|
|
134
|
+
function isExampleKey(value) {
|
|
135
|
+
const upper = value.toUpperCase();
|
|
136
|
+
return EXAMPLE_KEY_SUFFIXES.some(suffix => upper.endsWith(suffix));
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Scan a single file's content for secrets using 3-layer detection.
|
|
140
|
+
*/
|
|
141
|
+
function scanFileSecrets(content, filePath, ruleset) {
|
|
142
|
+
const findings = [];
|
|
143
|
+
const lines = content.split('\n');
|
|
144
|
+
const { patterns, entropy_threshold, context_keywords } = ruleset.secrets;
|
|
145
|
+
for (let i = 0; i < lines.length; i++) {
|
|
146
|
+
const line = lines[i];
|
|
147
|
+
const lineNum = i + 1;
|
|
148
|
+
// Skip shield-ignored lines
|
|
149
|
+
if ((0, ignore_js_1.isLineIgnored)(line))
|
|
150
|
+
continue;
|
|
151
|
+
// Layer 1: Regex
|
|
152
|
+
const regexHits = regexLayer(line, patterns);
|
|
153
|
+
// Layer 2: Entropy
|
|
154
|
+
const highEntropyTokens = entropyLayer(line, entropy_threshold);
|
|
155
|
+
// Layer 3: Context
|
|
156
|
+
const contextHit = contextLayer(line, filePath, context_keywords);
|
|
157
|
+
// Process regex hits
|
|
158
|
+
for (const { pattern, match } of regexHits) {
|
|
159
|
+
const matchedStr = match[0];
|
|
160
|
+
const column = (match.index ?? 0) + 1;
|
|
161
|
+
// Skip context-required patterns when no context is present
|
|
162
|
+
if (CONTEXT_REQUIRED_PATTERNS.has(pattern.id) && !contextHit) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
// Find the best entropy value for this match
|
|
166
|
+
const matchEntropy = shannonEntropy(matchedStr);
|
|
167
|
+
let severity = determineSeverity(pattern, true, matchEntropy, entropy_threshold, contextHit);
|
|
168
|
+
// Downgrade example/placeholder keys to warning
|
|
169
|
+
if (isExampleKey(matchedStr) && severity === 'critical') {
|
|
170
|
+
severity = 'warning';
|
|
171
|
+
}
|
|
172
|
+
if (severity !== 'info') {
|
|
173
|
+
findings.push({
|
|
174
|
+
file: filePath,
|
|
175
|
+
line: lineNum,
|
|
176
|
+
column,
|
|
177
|
+
type: pattern.id,
|
|
178
|
+
severity,
|
|
179
|
+
layers: {
|
|
180
|
+
regex: true,
|
|
181
|
+
entropy: matchEntropy,
|
|
182
|
+
context: contextHit,
|
|
183
|
+
},
|
|
184
|
+
matched: maskValue(matchedStr),
|
|
185
|
+
description: pattern.description,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Process high-entropy tokens without regex match (context required)
|
|
190
|
+
if (regexHits.length === 0 && highEntropyTokens.length > 0 && contextHit) {
|
|
191
|
+
for (const token of highEntropyTokens) {
|
|
192
|
+
// Don't flag tokens that look like common non-secret patterns
|
|
193
|
+
if (isLikelyNonSecret(token.token))
|
|
194
|
+
continue;
|
|
195
|
+
findings.push({
|
|
196
|
+
file: filePath,
|
|
197
|
+
line: lineNum,
|
|
198
|
+
column: token.column + 1,
|
|
199
|
+
type: 'high_entropy_secret',
|
|
200
|
+
severity: 'warning',
|
|
201
|
+
layers: {
|
|
202
|
+
regex: false,
|
|
203
|
+
entropy: token.entropy,
|
|
204
|
+
context: true,
|
|
205
|
+
},
|
|
206
|
+
matched: maskValue(token.token),
|
|
207
|
+
description: 'High-entropy string in secret context',
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return findings;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Check if a token is likely a non-secret (hash, uuid, etc.)
|
|
216
|
+
*/
|
|
217
|
+
function isLikelyNonSecret(token) {
|
|
218
|
+
// Pure hex strings of common hash lengths (MD5=32, SHA1=40, SHA256=64)
|
|
219
|
+
if (/^[0-9a-f]+$/i.test(token) && [32, 40, 64].includes(token.length)) {
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/scanner/secrets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ScanScore, LockStatus } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Determine lock status and badge eligibility from score.
|
|
4
|
+
*
|
|
5
|
+
* F → locked, no badge
|
|
6
|
+
* D-E → warning badge
|
|
7
|
+
* C → clean badge
|
|
8
|
+
* B → good badge
|
|
9
|
+
* A → excellent badge
|
|
10
|
+
*/
|
|
11
|
+
export declare function getLockStatus(score: ScanScore): LockStatus;
|
|
12
|
+
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/scoring/lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAgD1D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLockStatus = getLockStatus;
|
|
4
|
+
/**
|
|
5
|
+
* Determine lock status and badge eligibility from score.
|
|
6
|
+
*
|
|
7
|
+
* F → locked, no badge
|
|
8
|
+
* D-E → warning badge
|
|
9
|
+
* C → clean badge
|
|
10
|
+
* B → good badge
|
|
11
|
+
* A → excellent badge
|
|
12
|
+
*/
|
|
13
|
+
function getLockStatus(score) {
|
|
14
|
+
switch (score.grade) {
|
|
15
|
+
case 'F':
|
|
16
|
+
return {
|
|
17
|
+
isLocked: true,
|
|
18
|
+
canGenerateBadge: false,
|
|
19
|
+
canGenerateCleanBadge: false,
|
|
20
|
+
badgeType: 'locked',
|
|
21
|
+
message: `Badge generation LOCKED — ${score.lockReason ?? 'Grade F'}. Fix all critical findings first.`,
|
|
22
|
+
};
|
|
23
|
+
case 'E':
|
|
24
|
+
case 'D':
|
|
25
|
+
return {
|
|
26
|
+
isLocked: false,
|
|
27
|
+
canGenerateBadge: true,
|
|
28
|
+
canGenerateCleanBadge: false,
|
|
29
|
+
badgeType: 'warning',
|
|
30
|
+
message: `Grade ${score.grade} (${score.numericScore}/100) — Warning badge available.`,
|
|
31
|
+
};
|
|
32
|
+
case 'C':
|
|
33
|
+
return {
|
|
34
|
+
isLocked: false,
|
|
35
|
+
canGenerateBadge: true,
|
|
36
|
+
canGenerateCleanBadge: true,
|
|
37
|
+
badgeType: 'clean',
|
|
38
|
+
message: `Grade C (${score.numericScore}/100) — Clean badge available.`,
|
|
39
|
+
};
|
|
40
|
+
case 'B':
|
|
41
|
+
return {
|
|
42
|
+
isLocked: false,
|
|
43
|
+
canGenerateBadge: true,
|
|
44
|
+
canGenerateCleanBadge: true,
|
|
45
|
+
badgeType: 'good',
|
|
46
|
+
message: `Grade B (${score.numericScore}/100) — Good badge available.`,
|
|
47
|
+
};
|
|
48
|
+
case 'A':
|
|
49
|
+
return {
|
|
50
|
+
isLocked: false,
|
|
51
|
+
canGenerateBadge: true,
|
|
52
|
+
canGenerateCleanBadge: true,
|
|
53
|
+
badgeType: 'excellent',
|
|
54
|
+
message: `Grade A (${score.numericScore}/100) — Excellent badge available.`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/scoring/lock.ts"],"names":[],"mappings":";;AAWA,sCAgDC;AAzDD;;;;;;;;GAQG;AACH,SAAgB,aAAa,CAAC,KAAgB;IAC5C,QAAQ,KAAK,CAAC,KAAK,EAAE,CAAC;QACpB,KAAK,GAAG;YACN,OAAO;gBACL,QAAQ,EAAE,IAAI;gBACd,gBAAgB,EAAE,KAAK;gBACvB,qBAAqB,EAAE,KAAK;gBAC5B,SAAS,EAAE,QAAQ;gBACnB,OAAO,EAAE,6BAA6B,KAAK,CAAC,UAAU,IAAI,SAAS,oCAAoC;aACxG,CAAC;QAEJ,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,OAAO;gBACL,QAAQ,EAAE,KAAK;gBACf,gBAAgB,EAAE,IAAI;gBACtB,qBAAqB,EAAE,KAAK;gBAC5B,SAAS,EAAE,SAAS;gBACpB,OAAO,EAAE,SAAS,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,YAAY,kCAAkC;aACvF,CAAC;QAEJ,KAAK,GAAG;YACN,OAAO;gBACL,QAAQ,EAAE,KAAK;gBACf,gBAAgB,EAAE,IAAI;gBACtB,qBAAqB,EAAE,IAAI;gBAC3B,SAAS,EAAE,OAAO;gBAClB,OAAO,EAAE,YAAY,KAAK,CAAC,YAAY,gCAAgC;aACxE,CAAC;QAEJ,KAAK,GAAG;YACN,OAAO;gBACL,QAAQ,EAAE,KAAK;gBACf,gBAAgB,EAAE,IAAI;gBACtB,qBAAqB,EAAE,IAAI;gBAC3B,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,YAAY,KAAK,CAAC,YAAY,+BAA+B;aACvE,CAAC;QAEJ,KAAK,GAAG;YACN,OAAO;gBACL,QAAQ,EAAE,KAAK;gBACf,gBAAgB,EAAE,IAAI;gBACtB,qBAAqB,EAAE,IAAI;gBAC3B,SAAS,EAAE,WAAW;gBACtB,OAAO,EAAE,YAAY,KAAK,CAAC,YAAY,oCAAoC;aAC5E,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ScanResult, ScanScore } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Calculate security score from scan results.
|
|
4
|
+
*
|
|
5
|
+
* Deductions:
|
|
6
|
+
* - Critical (secrets critical + PII confirmed + MCP critical): -25/each
|
|
7
|
+
* - Warning (secrets warning + MCP warning): -10/each
|
|
8
|
+
* - Possible (PII possible): -5/each
|
|
9
|
+
* - Info: -2/each
|
|
10
|
+
*
|
|
11
|
+
* Special: Any critical finding → automatic F grade + isLocked=true
|
|
12
|
+
*/
|
|
13
|
+
export declare function calculateScore(result: ScanResult): ScanScore;
|
|
14
|
+
//# sourceMappingURL=score.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../src/scoring/score.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA4B/D;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAmD5D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateScore = calculateScore;
|
|
4
|
+
/**
|
|
5
|
+
* Deduction per finding severity.
|
|
6
|
+
*/
|
|
7
|
+
const DEDUCTIONS = {
|
|
8
|
+
critical: 25,
|
|
9
|
+
warning: 10,
|
|
10
|
+
possible: 5,
|
|
11
|
+
info: 2,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Grade thresholds (lower bound inclusive).
|
|
15
|
+
*/
|
|
16
|
+
const GRADE_MAP = [
|
|
17
|
+
{ min: 90, grade: 'A', label: 'Excellent' },
|
|
18
|
+
{ min: 75, grade: 'B', label: 'Good' },
|
|
19
|
+
{ min: 60, grade: 'C', label: 'Pass' },
|
|
20
|
+
{ min: 40, grade: 'D', label: 'Warning' },
|
|
21
|
+
{ min: 20, grade: 'E', label: 'Warning' },
|
|
22
|
+
{ min: 0, grade: 'F', label: 'Locked' },
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Calculate security score from scan results.
|
|
26
|
+
*
|
|
27
|
+
* Deductions:
|
|
28
|
+
* - Critical (secrets critical + PII confirmed + MCP critical): -25/each
|
|
29
|
+
* - Warning (secrets warning + MCP warning): -10/each
|
|
30
|
+
* - Possible (PII possible): -5/each
|
|
31
|
+
* - Info: -2/each
|
|
32
|
+
*
|
|
33
|
+
* Special: Any critical finding → automatic F grade + isLocked=true
|
|
34
|
+
*/
|
|
35
|
+
function calculateScore(result) {
|
|
36
|
+
const criticalCount = result.summary.critical +
|
|
37
|
+
result.summary.confirmedPii +
|
|
38
|
+
result.summary.mcpCritical +
|
|
39
|
+
result.summary.injectionCritical;
|
|
40
|
+
const warningCount = result.summary.warning +
|
|
41
|
+
result.summary.mcpWarning +
|
|
42
|
+
result.summary.injectionWarning;
|
|
43
|
+
const possibleCount = result.summary.possiblePii;
|
|
44
|
+
// Count info-level findings
|
|
45
|
+
const infoCount = result.secrets.filter(s => s.severity === 'info').length +
|
|
46
|
+
result.pii.filter(p => p.severity === 'info').length;
|
|
47
|
+
const totalDeduction = criticalCount * DEDUCTIONS.critical +
|
|
48
|
+
warningCount * DEDUCTIONS.warning +
|
|
49
|
+
possibleCount * DEDUCTIONS.possible +
|
|
50
|
+
infoCount * DEDUCTIONS.info;
|
|
51
|
+
const numericScore = Math.max(0, 100 - totalDeduction);
|
|
52
|
+
const breakdown = { criticalCount, warningCount, possibleCount, infoCount };
|
|
53
|
+
// Special rule: any critical → automatic F + locked
|
|
54
|
+
if (criticalCount > 0) {
|
|
55
|
+
return {
|
|
56
|
+
numericScore,
|
|
57
|
+
grade: 'F',
|
|
58
|
+
label: 'Locked',
|
|
59
|
+
isLocked: true,
|
|
60
|
+
breakdown,
|
|
61
|
+
lockReason: `${criticalCount} critical finding(s) detected — automatic lock`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Normal grade mapping
|
|
65
|
+
const entry = GRADE_MAP.find(g => numericScore >= g.min) ?? GRADE_MAP[GRADE_MAP.length - 1];
|
|
66
|
+
return {
|
|
67
|
+
numericScore,
|
|
68
|
+
grade: entry.grade,
|
|
69
|
+
label: entry.label,
|
|
70
|
+
isLocked: false,
|
|
71
|
+
breakdown,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/scoring/score.ts"],"names":[],"mappings":";;AAuCA,wCAmDC;AAxFD;;GAEG;AACH,MAAM,UAAU,GAAG;IACjB,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,CAAC;CACC,CAAC;AAEX;;GAEG;AACH,MAAM,SAAS,GAIV;IACH,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3C,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IACtC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IACtC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IACzC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IACzC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;CACxC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAAC,MAAkB;IAC/C,MAAM,aAAa,GACjB,MAAM,CAAC,OAAO,CAAC,QAAQ;QACvB,MAAM,CAAC,OAAO,CAAC,YAAY;QAC3B,MAAM,CAAC,OAAO,CAAC,WAAW;QAC1B,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC;IAEnC,MAAM,YAAY,GAChB,MAAM,CAAC,OAAO,CAAC,OAAO;QACtB,MAAM,CAAC,OAAO,CAAC,UAAU;QACzB,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC;IAElC,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAEjD,4BAA4B;IAC5B,MAAM,SAAS,GACb,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM;QACxD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAEvD,MAAM,cAAc,GAClB,aAAa,GAAG,UAAU,CAAC,QAAQ;QACnC,YAAY,GAAG,UAAU,CAAC,OAAO;QACjC,aAAa,GAAG,UAAU,CAAC,QAAQ;QACnC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC;IAE9B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,cAAc,CAAC,CAAC;IAEvD,MAAM,SAAS,GAAG,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;IAE5E,oDAAoD;IACpD,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,YAAY;YACZ,KAAK,EAAE,GAAG;YACV,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;YACd,SAAS;YACT,UAAU,EAAE,GAAG,aAAa,gDAAgD;SAC7E,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE5F,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ,EAAE,KAAK;QACf,SAAS;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
export interface MCPCheckItem {
|
|
2
|
+
status: 'critical' | 'warning' | 'pass';
|
|
3
|
+
detail: string;
|
|
4
|
+
}
|
|
5
|
+
export interface MCPFinding {
|
|
6
|
+
file: string;
|
|
7
|
+
items: {
|
|
8
|
+
auth: MCPCheckItem;
|
|
9
|
+
secrets: MCPCheckItem;
|
|
10
|
+
toolMeta: MCPCheckItem;
|
|
11
|
+
permissions: MCPCheckItem;
|
|
12
|
+
logging: MCPCheckItem;
|
|
13
|
+
};
|
|
14
|
+
overallSeverity: 'critical' | 'warning' | 'pass';
|
|
15
|
+
failedCount: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ScanScore {
|
|
18
|
+
numericScore: number;
|
|
19
|
+
grade: 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
|
|
20
|
+
label: 'Excellent' | 'Good' | 'Pass' | 'Warning' | 'Locked';
|
|
21
|
+
isLocked: boolean;
|
|
22
|
+
breakdown: {
|
|
23
|
+
criticalCount: number;
|
|
24
|
+
warningCount: number;
|
|
25
|
+
possibleCount: number;
|
|
26
|
+
infoCount: number;
|
|
27
|
+
};
|
|
28
|
+
lockReason?: string;
|
|
29
|
+
}
|
|
30
|
+
export type BadgeType = 'locked' | 'warning' | 'clean' | 'good' | 'excellent';
|
|
31
|
+
export interface LockStatus {
|
|
32
|
+
isLocked: boolean;
|
|
33
|
+
canGenerateBadge: boolean;
|
|
34
|
+
canGenerateCleanBadge: boolean;
|
|
35
|
+
badgeType: BadgeType;
|
|
36
|
+
message: string;
|
|
37
|
+
}
|
|
38
|
+
export interface SealedResult {
|
|
39
|
+
resultHash: string;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
rulesetVersion: string;
|
|
42
|
+
badgeUUID?: string;
|
|
43
|
+
verifyURL?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface SecretFinding {
|
|
46
|
+
file: string;
|
|
47
|
+
line: number;
|
|
48
|
+
column: number;
|
|
49
|
+
type: string;
|
|
50
|
+
severity: 'critical' | 'warning' | 'info';
|
|
51
|
+
layers: {
|
|
52
|
+
regex: boolean;
|
|
53
|
+
entropy: number;
|
|
54
|
+
context: boolean;
|
|
55
|
+
};
|
|
56
|
+
matched: string;
|
|
57
|
+
description: string;
|
|
58
|
+
}
|
|
59
|
+
export interface PIIFinding {
|
|
60
|
+
file: string;
|
|
61
|
+
line: number;
|
|
62
|
+
column: number;
|
|
63
|
+
type: string;
|
|
64
|
+
severity: 'confirmed' | 'possible' | 'info';
|
|
65
|
+
layers: {
|
|
66
|
+
regex: boolean;
|
|
67
|
+
checksum: boolean | null;
|
|
68
|
+
};
|
|
69
|
+
matched: string;
|
|
70
|
+
description: string;
|
|
71
|
+
locale: 'kr' | 'global';
|
|
72
|
+
}
|
|
73
|
+
export interface InjectionFinding {
|
|
74
|
+
file: string;
|
|
75
|
+
line: number;
|
|
76
|
+
type: 'direct' | 'indirect' | 'encoded' | 'structural';
|
|
77
|
+
severity: 'critical' | 'warning' | 'info';
|
|
78
|
+
layers: {
|
|
79
|
+
keyword: boolean;
|
|
80
|
+
structure: boolean;
|
|
81
|
+
};
|
|
82
|
+
pattern: string;
|
|
83
|
+
context: string;
|
|
84
|
+
description: string;
|
|
85
|
+
}
|
|
86
|
+
export interface FixitGuide {
|
|
87
|
+
title: string;
|
|
88
|
+
steps: string[];
|
|
89
|
+
code?: string;
|
|
90
|
+
severity: 'critical' | 'warning';
|
|
91
|
+
references?: string[];
|
|
92
|
+
}
|
|
93
|
+
export interface EvidencePack {
|
|
94
|
+
generatedAt: string;
|
|
95
|
+
toolVersion: string;
|
|
96
|
+
rulesetVersion: string;
|
|
97
|
+
scanTarget: string;
|
|
98
|
+
filesScanned: number;
|
|
99
|
+
filesExcluded: number;
|
|
100
|
+
scanDuration: string;
|
|
101
|
+
score: ScanScore;
|
|
102
|
+
lockStatus: LockStatus;
|
|
103
|
+
findings: {
|
|
104
|
+
secrets: SecretFinding[];
|
|
105
|
+
pii: PIIFinding[];
|
|
106
|
+
mcp: MCPFinding[];
|
|
107
|
+
injection: InjectionFinding[];
|
|
108
|
+
};
|
|
109
|
+
fixitSummary: {
|
|
110
|
+
totalIssues: number;
|
|
111
|
+
criticalIssues: number;
|
|
112
|
+
fixitGuidesAvailable: number;
|
|
113
|
+
};
|
|
114
|
+
integrity: {
|
|
115
|
+
rulesetHash: string;
|
|
116
|
+
resultHash: string;
|
|
117
|
+
badgeUUID?: string;
|
|
118
|
+
verifyURL?: string;
|
|
119
|
+
};
|
|
120
|
+
disclaimer: string;
|
|
121
|
+
}
|
|
122
|
+
export interface ScanResult {
|
|
123
|
+
secrets: SecretFinding[];
|
|
124
|
+
pii: PIIFinding[];
|
|
125
|
+
mcp: MCPFinding[];
|
|
126
|
+
injection: InjectionFinding[];
|
|
127
|
+
summary: {
|
|
128
|
+
filesScanned: number;
|
|
129
|
+
filesExcluded: number;
|
|
130
|
+
timeMs: number;
|
|
131
|
+
critical: number;
|
|
132
|
+
warning: number;
|
|
133
|
+
confirmedPii: number;
|
|
134
|
+
possiblePii: number;
|
|
135
|
+
mcpCritical: number;
|
|
136
|
+
mcpWarning: number;
|
|
137
|
+
injectionCritical: number;
|
|
138
|
+
injectionWarning: number;
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
export interface ScanConfig {
|
|
142
|
+
targetPath: string;
|
|
143
|
+
format: 'terminal' | 'json';
|
|
144
|
+
ignorePath?: string;
|
|
145
|
+
rulesetPath?: string;
|
|
146
|
+
}
|
|
147
|
+
export interface SecretPattern {
|
|
148
|
+
id: string;
|
|
149
|
+
name: string;
|
|
150
|
+
regex: string;
|
|
151
|
+
description: string;
|
|
152
|
+
severity_override?: 'critical' | 'warning';
|
|
153
|
+
}
|
|
154
|
+
export interface PIIPattern {
|
|
155
|
+
id: string;
|
|
156
|
+
name: string;
|
|
157
|
+
regex: string;
|
|
158
|
+
description: string;
|
|
159
|
+
locale: 'kr' | 'global';
|
|
160
|
+
has_checksum: boolean;
|
|
161
|
+
}
|
|
162
|
+
export interface MCPPattern {
|
|
163
|
+
id: string;
|
|
164
|
+
name: string;
|
|
165
|
+
type: 'auth_field' | 'dangerous_tool' | 'permission_pattern' | 'logging_field';
|
|
166
|
+
values: string[];
|
|
167
|
+
description: string;
|
|
168
|
+
}
|
|
169
|
+
export interface InjectionPattern {
|
|
170
|
+
id: string;
|
|
171
|
+
name: string;
|
|
172
|
+
regex: string;
|
|
173
|
+
type: 'direct' | 'indirect';
|
|
174
|
+
description: string;
|
|
175
|
+
}
|
|
176
|
+
export interface Ruleset {
|
|
177
|
+
version: string;
|
|
178
|
+
sha256: string;
|
|
179
|
+
secrets: {
|
|
180
|
+
patterns: SecretPattern[];
|
|
181
|
+
entropy_threshold: number;
|
|
182
|
+
context_keywords: string[];
|
|
183
|
+
};
|
|
184
|
+
pii: {
|
|
185
|
+
patterns: PIIPattern[];
|
|
186
|
+
};
|
|
187
|
+
mcp: {
|
|
188
|
+
config_files: string[];
|
|
189
|
+
auth_fields: string[];
|
|
190
|
+
dangerous_tool_keywords: string[];
|
|
191
|
+
permission_patterns: MCPPattern[];
|
|
192
|
+
logging_fields: string[];
|
|
193
|
+
};
|
|
194
|
+
injection: {
|
|
195
|
+
direct_patterns: InjectionPattern[];
|
|
196
|
+
indirect_patterns: InjectionPattern[];
|
|
197
|
+
structural: {
|
|
198
|
+
html_comment_regex: string;
|
|
199
|
+
markdown_comment_regex: string;
|
|
200
|
+
zero_width_chars: string[];
|
|
201
|
+
tool_length_multiplier: number;
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|