asterscanner 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 +242 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/patterns.d.ts +18 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +314 -0
- package/dist/patterns.js.map +1 -0
- package/dist/scanner.d.ts +46 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +160 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scoring.d.ts +30 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +62 -0
- package/dist/scoring.js.map +1 -0
- package/dist/skill-schema.d.ts +456 -0
- package/dist/skill-schema.d.ts.map +1 -0
- package/dist/skill-schema.js +531 -0
- package/dist/skill-schema.js.map +1 -0
- package/dist/skill-tester.d.ts +119 -0
- package/dist/skill-tester.d.ts.map +1 -0
- package/dist/skill-tester.js +334 -0
- package/dist/skill-tester.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/dist/scanner.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { SECURITY_PATTERNS } from "./patterns.js";
|
|
2
|
+
import { calculateScore, scorePassesThreshold } from "./scoring.js";
|
|
3
|
+
/**
|
|
4
|
+
* Default scan options
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_OPTIONS = {
|
|
7
|
+
minScore: 50,
|
|
8
|
+
categories: ["secrets", "code_execution", "file_system", "network", "credentials", "system"],
|
|
9
|
+
severities: ["critical", "high", "medium", "low", "info"],
|
|
10
|
+
customPatterns: [],
|
|
11
|
+
includeInfoInScore: false,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Security scanner for skill content
|
|
15
|
+
*/
|
|
16
|
+
export class Scanner {
|
|
17
|
+
options;
|
|
18
|
+
patterns;
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
21
|
+
this.patterns = this.buildPatternList();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the list of patterns to use based on options
|
|
25
|
+
*/
|
|
26
|
+
buildPatternList() {
|
|
27
|
+
const patterns = [
|
|
28
|
+
...SECURITY_PATTERNS.filter((p) => this.options.categories.includes(p.category) &&
|
|
29
|
+
this.options.severities.includes(p.severity)),
|
|
30
|
+
...this.options.customPatterns,
|
|
31
|
+
];
|
|
32
|
+
return patterns;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Sanitize matched content for display (truncate and mask sensitive parts)
|
|
36
|
+
*/
|
|
37
|
+
sanitizeMatch(match) {
|
|
38
|
+
if (match.length > 50) {
|
|
39
|
+
return match.substring(0, 47) + "...";
|
|
40
|
+
}
|
|
41
|
+
// Mask potential secrets
|
|
42
|
+
if (match.includes("=") || match.includes(":")) {
|
|
43
|
+
const parts = match.split(/[:=]/);
|
|
44
|
+
if (parts.length === 2 && parts[1].length > 4) {
|
|
45
|
+
const visible = parts[1].substring(0, 4);
|
|
46
|
+
return `${parts[0]}=${visible}${"*".repeat(Math.min(parts[1].length - 4, 10))}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return match;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Scan a single line for security issues
|
|
53
|
+
*/
|
|
54
|
+
scanLine(line, lineNumber) {
|
|
55
|
+
const issues = [];
|
|
56
|
+
for (const patternDef of this.patterns) {
|
|
57
|
+
// Reset lastIndex for global patterns
|
|
58
|
+
patternDef.pattern.lastIndex = 0;
|
|
59
|
+
let match;
|
|
60
|
+
while ((match = patternDef.pattern.exec(line)) !== null) {
|
|
61
|
+
issues.push({
|
|
62
|
+
patternId: patternDef.id,
|
|
63
|
+
type: patternDef.type,
|
|
64
|
+
category: patternDef.category,
|
|
65
|
+
severity: patternDef.severity,
|
|
66
|
+
message: patternDef.message,
|
|
67
|
+
line: lineNumber,
|
|
68
|
+
column: match.index + 1,
|
|
69
|
+
match: this.sanitizeMatch(match[0]),
|
|
70
|
+
recommendation: patternDef.recommendation,
|
|
71
|
+
});
|
|
72
|
+
// Prevent infinite loops for patterns that match empty strings
|
|
73
|
+
if (match[0].length === 0) {
|
|
74
|
+
patternDef.pattern.lastIndex++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return issues;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Scan content for security issues
|
|
82
|
+
*/
|
|
83
|
+
scan(content) {
|
|
84
|
+
const startTime = Date.now();
|
|
85
|
+
const lines = content.split("\n");
|
|
86
|
+
const issues = [];
|
|
87
|
+
for (let i = 0; i < lines.length; i++) {
|
|
88
|
+
const lineIssues = this.scanLine(lines[i], i + 1);
|
|
89
|
+
issues.push(...lineIssues);
|
|
90
|
+
}
|
|
91
|
+
// Sort issues by severity, then by line number
|
|
92
|
+
const severityOrder = {
|
|
93
|
+
critical: 0,
|
|
94
|
+
high: 1,
|
|
95
|
+
medium: 2,
|
|
96
|
+
low: 3,
|
|
97
|
+
info: 4,
|
|
98
|
+
};
|
|
99
|
+
issues.sort((a, b) => {
|
|
100
|
+
const severityDiff = severityOrder[a.severity] - severityOrder[b.severity];
|
|
101
|
+
if (severityDiff !== 0)
|
|
102
|
+
return severityDiff;
|
|
103
|
+
return a.line - b.line;
|
|
104
|
+
});
|
|
105
|
+
const score = calculateScore(issues, this.options.includeInfoInScore);
|
|
106
|
+
const passed = scorePassesThreshold(score, this.options.minScore);
|
|
107
|
+
// Build summary
|
|
108
|
+
const summary = {
|
|
109
|
+
critical: issues.filter((i) => i.severity === "critical").length,
|
|
110
|
+
high: issues.filter((i) => i.severity === "high").length,
|
|
111
|
+
medium: issues.filter((i) => i.severity === "medium").length,
|
|
112
|
+
low: issues.filter((i) => i.severity === "low").length,
|
|
113
|
+
info: issues.filter((i) => i.severity === "info").length,
|
|
114
|
+
total: issues.length,
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
score,
|
|
118
|
+
passed,
|
|
119
|
+
issues,
|
|
120
|
+
summary,
|
|
121
|
+
metadata: {
|
|
122
|
+
scannedAt: new Date().toISOString(),
|
|
123
|
+
contentLength: content.length,
|
|
124
|
+
lineCount: lines.length,
|
|
125
|
+
scanDurationMs: Date.now() - startTime,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Quick check if content passes security requirements
|
|
131
|
+
*/
|
|
132
|
+
passes(content) {
|
|
133
|
+
return this.scan(content).passed;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get the current options
|
|
137
|
+
*/
|
|
138
|
+
getOptions() {
|
|
139
|
+
return { ...this.options };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get the active patterns
|
|
143
|
+
*/
|
|
144
|
+
getPatterns() {
|
|
145
|
+
return [...this.patterns];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Create a new scanner instance
|
|
150
|
+
*/
|
|
151
|
+
export function createScanner(options) {
|
|
152
|
+
return new Scanner(options);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Quick scan function for simple use cases
|
|
156
|
+
*/
|
|
157
|
+
export function scan(content, options) {
|
|
158
|
+
return new Scanner(options).scan(content);
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SecurityIssue, Severity } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Weight deductions for each severity level
|
|
4
|
+
*/
|
|
5
|
+
export declare const SEVERITY_WEIGHTS: Record<Severity, number>;
|
|
6
|
+
/**
|
|
7
|
+
* Calculate security score based on issues found
|
|
8
|
+
*
|
|
9
|
+
* @param issues - List of security issues
|
|
10
|
+
* @param includeInfo - Whether to include info-level issues (default: false)
|
|
11
|
+
* @returns Score from 0-100
|
|
12
|
+
*/
|
|
13
|
+
export declare function calculateScore(issues: SecurityIssue[], includeInfo?: boolean): number;
|
|
14
|
+
/**
|
|
15
|
+
* Determine if a score passes the minimum threshold
|
|
16
|
+
*
|
|
17
|
+
* @param score - The security score
|
|
18
|
+
* @param minScore - Minimum passing score (default: 50)
|
|
19
|
+
* @returns Whether the score passes
|
|
20
|
+
*/
|
|
21
|
+
export declare function scorePassesThreshold(score: number, minScore?: number): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Get a human-readable rating based on score
|
|
24
|
+
*/
|
|
25
|
+
export declare function getScoreRating(score: number): "excellent" | "good" | "fair" | "poor" | "critical";
|
|
26
|
+
/**
|
|
27
|
+
* Get a color code for the score (for terminal output)
|
|
28
|
+
*/
|
|
29
|
+
export declare function getScoreColor(score: number): "green" | "yellow" | "red";
|
|
30
|
+
//# sourceMappingURL=scoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAMrD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EAAE,EACvB,WAAW,GAAE,OAAe,GAC3B,MAAM,CAWR;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAW,GACpB,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,GACZ,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAMrD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAIvE"}
|
package/dist/scoring.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weight deductions for each severity level
|
|
3
|
+
*/
|
|
4
|
+
export const SEVERITY_WEIGHTS = {
|
|
5
|
+
critical: 25,
|
|
6
|
+
high: 15,
|
|
7
|
+
medium: 10,
|
|
8
|
+
low: 5,
|
|
9
|
+
info: 0,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Calculate security score based on issues found
|
|
13
|
+
*
|
|
14
|
+
* @param issues - List of security issues
|
|
15
|
+
* @param includeInfo - Whether to include info-level issues (default: false)
|
|
16
|
+
* @returns Score from 0-100
|
|
17
|
+
*/
|
|
18
|
+
export function calculateScore(issues, includeInfo = false) {
|
|
19
|
+
let score = 100;
|
|
20
|
+
for (const issue of issues) {
|
|
21
|
+
if (!includeInfo && issue.severity === "info") {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
score -= SEVERITY_WEIGHTS[issue.severity];
|
|
25
|
+
}
|
|
26
|
+
return Math.max(0, score);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Determine if a score passes the minimum threshold
|
|
30
|
+
*
|
|
31
|
+
* @param score - The security score
|
|
32
|
+
* @param minScore - Minimum passing score (default: 50)
|
|
33
|
+
* @returns Whether the score passes
|
|
34
|
+
*/
|
|
35
|
+
export function scorePassesThreshold(score, minScore = 50) {
|
|
36
|
+
return score >= minScore;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get a human-readable rating based on score
|
|
40
|
+
*/
|
|
41
|
+
export function getScoreRating(score) {
|
|
42
|
+
if (score >= 90)
|
|
43
|
+
return "excellent";
|
|
44
|
+
if (score >= 70)
|
|
45
|
+
return "good";
|
|
46
|
+
if (score >= 50)
|
|
47
|
+
return "fair";
|
|
48
|
+
if (score >= 25)
|
|
49
|
+
return "poor";
|
|
50
|
+
return "critical";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get a color code for the score (for terminal output)
|
|
54
|
+
*/
|
|
55
|
+
export function getScoreColor(score) {
|
|
56
|
+
if (score >= 70)
|
|
57
|
+
return "green";
|
|
58
|
+
if (score >= 50)
|
|
59
|
+
return "yellow";
|
|
60
|
+
return "red";
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=scoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.js","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IACxD,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,EAAE;IACR,MAAM,EAAE,EAAE;IACV,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;CACR,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAuB,EACvB,cAAuB,KAAK;IAE5B,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YAC9C,SAAS;QACX,CAAC;QACD,KAAK,IAAI,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,WAAmB,EAAE;IAErB,OAAO,KAAK,IAAI,QAAQ,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAa;IAEb,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,WAAW,CAAC;IACpC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IAC/B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,OAAO,CAAC;IAChC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,QAAQ,CAAC;IACjC,OAAO,KAAK,CAAC;AACf,CAAC"}
|