aura-security 0.4.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/LICENSE +21 -0
- package/README.md +446 -0
- package/deploy/AWS-DEPLOYMENT.md +358 -0
- package/deploy/terraform/main.tf +362 -0
- package/deploy/terraform/terraform.tfvars.example +6 -0
- package/dist/agents/base.d.ts +44 -0
- package/dist/agents/base.js +96 -0
- package/dist/agents/index.d.ts +14 -0
- package/dist/agents/index.js +17 -0
- package/dist/agents/policy/evaluator.d.ts +15 -0
- package/dist/agents/policy/evaluator.js +183 -0
- package/dist/agents/policy/index.d.ts +12 -0
- package/dist/agents/policy/index.js +15 -0
- package/dist/agents/policy/validator.d.ts +15 -0
- package/dist/agents/policy/validator.js +182 -0
- package/dist/agents/scanners/gitleaks.d.ts +14 -0
- package/dist/agents/scanners/gitleaks.js +155 -0
- package/dist/agents/scanners/grype.d.ts +14 -0
- package/dist/agents/scanners/grype.js +109 -0
- package/dist/agents/scanners/index.d.ts +15 -0
- package/dist/agents/scanners/index.js +27 -0
- package/dist/agents/scanners/npm-audit.d.ts +13 -0
- package/dist/agents/scanners/npm-audit.js +129 -0
- package/dist/agents/scanners/semgrep.d.ts +14 -0
- package/dist/agents/scanners/semgrep.js +131 -0
- package/dist/agents/scanners/trivy.d.ts +14 -0
- package/dist/agents/scanners/trivy.js +122 -0
- package/dist/agents/types.d.ts +137 -0
- package/dist/agents/types.js +91 -0
- package/dist/auditor/index.d.ts +3 -0
- package/dist/auditor/index.js +2 -0
- package/dist/auditor/pipeline.d.ts +19 -0
- package/dist/auditor/pipeline.js +240 -0
- package/dist/auditor/validator.d.ts +17 -0
- package/dist/auditor/validator.js +58 -0
- package/dist/aura/client.d.ts +29 -0
- package/dist/aura/client.js +125 -0
- package/dist/aura/index.d.ts +4 -0
- package/dist/aura/index.js +2 -0
- package/dist/aura/server.d.ts +45 -0
- package/dist/aura/server.js +343 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.js +1433 -0
- package/dist/client/index.d.ts +41 -0
- package/dist/client/index.js +170 -0
- package/dist/compliance/index.d.ts +40 -0
- package/dist/compliance/index.js +292 -0
- package/dist/database/index.d.ts +77 -0
- package/dist/database/index.js +395 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +762 -0
- package/dist/integrations/aura-scanner.d.ts +69 -0
- package/dist/integrations/aura-scanner.js +155 -0
- package/dist/integrations/aws-scanner.d.ts +63 -0
- package/dist/integrations/aws-scanner.js +624 -0
- package/dist/integrations/config.d.ts +69 -0
- package/dist/integrations/config.js +212 -0
- package/dist/integrations/github.d.ts +45 -0
- package/dist/integrations/github.js +201 -0
- package/dist/integrations/gitlab.d.ts +36 -0
- package/dist/integrations/gitlab.js +110 -0
- package/dist/integrations/index.d.ts +11 -0
- package/dist/integrations/index.js +11 -0
- package/dist/integrations/local-scanner.d.ts +146 -0
- package/dist/integrations/local-scanner.js +1654 -0
- package/dist/integrations/notifications.d.ts +99 -0
- package/dist/integrations/notifications.js +305 -0
- package/dist/integrations/scanners.d.ts +57 -0
- package/dist/integrations/scanners.js +217 -0
- package/dist/integrations/slop-scanner.d.ts +69 -0
- package/dist/integrations/slop-scanner.js +155 -0
- package/dist/integrations/webhook.d.ts +37 -0
- package/dist/integrations/webhook.js +256 -0
- package/dist/orchestrator/index.d.ts +72 -0
- package/dist/orchestrator/index.js +187 -0
- package/dist/output/index.d.ts +152 -0
- package/dist/output/index.js +399 -0
- package/dist/pipeline/index.d.ts +72 -0
- package/dist/pipeline/index.js +313 -0
- package/dist/sbom/index.d.ts +94 -0
- package/dist/sbom/index.js +298 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/input.schema.d.ts +87 -0
- package/dist/schemas/input.schema.js +44 -0
- package/dist/schemas/output.schema.d.ts +115 -0
- package/dist/schemas/output.schema.js +64 -0
- package/dist/serve-visualizer.d.ts +2 -0
- package/dist/serve-visualizer.js +78 -0
- package/dist/slop/client.d.ts +29 -0
- package/dist/slop/client.js +125 -0
- package/dist/slop/index.d.ts +4 -0
- package/dist/slop/index.js +2 -0
- package/dist/slop/server.d.ts +45 -0
- package/dist/slop/server.js +343 -0
- package/dist/types/events.d.ts +62 -0
- package/dist/types/events.js +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/visualizer/index.d.ts +4 -0
- package/dist/visualizer/index.js +181 -0
- package/dist/websocket/index.d.ts +88 -0
- package/dist/websocket/index.js +195 -0
- package/dist/zones/index.d.ts +7 -0
- package/dist/zones/index.js +7 -0
- package/dist/zones/manager.d.ts +101 -0
- package/dist/zones/manager.js +304 -0
- package/dist/zones/types.d.ts +78 -0
- package/dist/zones/types.js +33 -0
- package/package.json +84 -0
- package/visualizer/app.js +0 -0
- package/visualizer/index-minimal.html +1771 -0
- package/visualizer/index.html +2933 -0
- package/visualizer/landing.html +1328 -0
- package/visualizer/styles.css +0 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
// Output Format Generators
|
|
2
|
+
// Supports: SARIF 2.1.0, JUnit XML, JSON Summary, GitLab Security Report
|
|
3
|
+
// Severity to SARIF level mapping
|
|
4
|
+
function severityToLevel(severity) {
|
|
5
|
+
switch (severity.toLowerCase()) {
|
|
6
|
+
case 'critical':
|
|
7
|
+
case 'high':
|
|
8
|
+
return 'error';
|
|
9
|
+
case 'medium':
|
|
10
|
+
return 'warning';
|
|
11
|
+
case 'low':
|
|
12
|
+
return 'note';
|
|
13
|
+
default:
|
|
14
|
+
return 'none';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// Severity to security-severity score (for GitHub)
|
|
18
|
+
function severityToScore(severity) {
|
|
19
|
+
switch (severity.toLowerCase()) {
|
|
20
|
+
case 'critical': return '9.0';
|
|
21
|
+
case 'high': return '7.0';
|
|
22
|
+
case 'medium': return '5.0';
|
|
23
|
+
case 'low': return '3.0';
|
|
24
|
+
default: return '1.0';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Generate SARIF report from scan results
|
|
28
|
+
export function toSARIF(result, targetPath) {
|
|
29
|
+
const rules = [];
|
|
30
|
+
const results = [];
|
|
31
|
+
const ruleIds = new Set();
|
|
32
|
+
// Helper to add rule if not exists
|
|
33
|
+
const addRule = (id, name, description, severity, tags) => {
|
|
34
|
+
if (!ruleIds.has(id)) {
|
|
35
|
+
ruleIds.add(id);
|
|
36
|
+
rules.push({
|
|
37
|
+
id,
|
|
38
|
+
name,
|
|
39
|
+
shortDescription: { text: description },
|
|
40
|
+
defaultConfiguration: { level: severityToLevel(severity) },
|
|
41
|
+
properties: {
|
|
42
|
+
tags,
|
|
43
|
+
'security-severity': severityToScore(severity)
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
// Process secrets
|
|
49
|
+
for (const secret of result.secrets) {
|
|
50
|
+
const ruleId = `secret/${secret.type.toLowerCase().replace(/\s+/g, '-')}`;
|
|
51
|
+
addRule(ruleId, `Secret: ${secret.type}`, `Potential secret or credential found: ${secret.type}`, secret.severity, ['security', 'secret-detection']);
|
|
52
|
+
results.push({
|
|
53
|
+
ruleId,
|
|
54
|
+
level: severityToLevel(secret.severity),
|
|
55
|
+
message: { text: `Found ${secret.type} in source code` },
|
|
56
|
+
locations: [{
|
|
57
|
+
physicalLocation: {
|
|
58
|
+
artifactLocation: {
|
|
59
|
+
uri: secret.file.replace(targetPath ? targetPath + '/' : '', ''),
|
|
60
|
+
uriBaseId: '%SRCROOT%'
|
|
61
|
+
},
|
|
62
|
+
region: {
|
|
63
|
+
startLine: secret.line
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// Process package vulnerabilities
|
|
70
|
+
for (const pkg of result.packages) {
|
|
71
|
+
const ruleId = pkg.vulnId ? `vuln/${pkg.vulnId}` : `vuln/${pkg.name}`;
|
|
72
|
+
addRule(ruleId, pkg.vulnId || `Vulnerability in ${pkg.name}`, pkg.title || `Security vulnerability in ${pkg.name}@${pkg.version}`, pkg.severity, ['security', 'dependency', 'vulnerability']);
|
|
73
|
+
results.push({
|
|
74
|
+
ruleId,
|
|
75
|
+
level: severityToLevel(pkg.severity),
|
|
76
|
+
message: {
|
|
77
|
+
text: `${pkg.name}@${pkg.version}: ${pkg.title || pkg.vulnId || 'vulnerability found'}${pkg.fixedVersion ? ` (fix: ${pkg.fixedVersion})` : ''}`
|
|
78
|
+
},
|
|
79
|
+
fixes: pkg.fixedVersion ? [{
|
|
80
|
+
description: { text: `Upgrade to version ${pkg.fixedVersion}` }
|
|
81
|
+
}] : undefined
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Process SAST findings
|
|
85
|
+
for (const sast of result.sastFindings) {
|
|
86
|
+
const ruleId = `sast/${sast.rule.replace(/[^a-zA-Z0-9-]/g, '-')}`;
|
|
87
|
+
addRule(ruleId, sast.rule, sast.message, sast.severity, ['security', 'sast']);
|
|
88
|
+
results.push({
|
|
89
|
+
ruleId,
|
|
90
|
+
level: severityToLevel(sast.severity),
|
|
91
|
+
message: { text: sast.message },
|
|
92
|
+
locations: [{
|
|
93
|
+
physicalLocation: {
|
|
94
|
+
artifactLocation: {
|
|
95
|
+
uri: sast.file.replace(targetPath ? targetPath + '/' : '', ''),
|
|
96
|
+
uriBaseId: '%SRCROOT%'
|
|
97
|
+
},
|
|
98
|
+
region: {
|
|
99
|
+
startLine: sast.line
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}]
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Process IaC findings
|
|
106
|
+
for (const iac of result.iacFindings) {
|
|
107
|
+
const ruleId = `iac/${iac.checkId}`;
|
|
108
|
+
addRule(ruleId, iac.checkId, iac.title, iac.severity, ['security', 'iac', iac.checkType]);
|
|
109
|
+
results.push({
|
|
110
|
+
ruleId,
|
|
111
|
+
level: severityToLevel(iac.severity),
|
|
112
|
+
message: { text: `${iac.title} - Resource: ${iac.resource}` },
|
|
113
|
+
locations: [{
|
|
114
|
+
physicalLocation: {
|
|
115
|
+
artifactLocation: {
|
|
116
|
+
uri: iac.file.replace(targetPath ? targetPath + '/' : '', ''),
|
|
117
|
+
uriBaseId: '%SRCROOT%'
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}],
|
|
121
|
+
fixes: iac.guideline ? [{
|
|
122
|
+
description: { text: iac.guideline }
|
|
123
|
+
}] : undefined
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Process Dockerfile findings
|
|
127
|
+
for (const docker of result.dockerfileFindings) {
|
|
128
|
+
const ruleId = `dockerfile/${docker.code}`;
|
|
129
|
+
addRule(ruleId, docker.code, docker.message, docker.severity, ['security', 'dockerfile', 'container']);
|
|
130
|
+
results.push({
|
|
131
|
+
ruleId,
|
|
132
|
+
level: severityToLevel(docker.severity),
|
|
133
|
+
message: { text: docker.message },
|
|
134
|
+
locations: [{
|
|
135
|
+
physicalLocation: {
|
|
136
|
+
artifactLocation: {
|
|
137
|
+
uri: docker.file.replace(targetPath ? targetPath + '/' : '', ''),
|
|
138
|
+
uriBaseId: '%SRCROOT%'
|
|
139
|
+
},
|
|
140
|
+
region: {
|
|
141
|
+
startLine: docker.line
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}]
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
$schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json',
|
|
149
|
+
version: '2.1.0',
|
|
150
|
+
runs: [{
|
|
151
|
+
tool: {
|
|
152
|
+
driver: {
|
|
153
|
+
name: 'AuraSecurity',
|
|
154
|
+
informationUri: 'https://github.com/aurasecurity/aura-security',
|
|
155
|
+
version: '0.2.0',
|
|
156
|
+
rules
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
results,
|
|
160
|
+
invocations: [{
|
|
161
|
+
executionSuccessful: true,
|
|
162
|
+
endTimeUtc: new Date().toISOString()
|
|
163
|
+
}]
|
|
164
|
+
}]
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// ============ JUnit XML Format ============
|
|
168
|
+
export function toJUnit(result) {
|
|
169
|
+
const totalTests = result.secrets.length + result.packages.length +
|
|
170
|
+
result.sastFindings.length + result.iacFindings.length +
|
|
171
|
+
result.dockerfileFindings.length;
|
|
172
|
+
const failures = result.secrets.filter(s => s.severity === 'critical' || s.severity === 'high').length +
|
|
173
|
+
result.packages.filter(p => p.severity === 'critical' || p.severity === 'high').length +
|
|
174
|
+
result.iacFindings.filter(i => i.severity === 'critical' || i.severity === 'high').length +
|
|
175
|
+
result.dockerfileFindings.filter(d => d.severity === 'critical' || d.severity === 'high').length;
|
|
176
|
+
let xml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
177
|
+
<testsuites name="AuraSecurity Security Scan" tests="${totalTests}" failures="${failures}" time="0">
|
|
178
|
+
<testsuite name="Secrets" tests="${result.secrets.length}" failures="${result.secrets.filter(s => s.severity === 'critical' || s.severity === 'high').length}">
|
|
179
|
+
`;
|
|
180
|
+
for (const secret of result.secrets) {
|
|
181
|
+
const isFailure = secret.severity === 'critical' || secret.severity === 'high';
|
|
182
|
+
xml += ` <testcase name="${escapeXml(secret.type)}" classname="${escapeXml(secret.file)}">\n`;
|
|
183
|
+
if (isFailure) {
|
|
184
|
+
xml += ` <failure message="${escapeXml(secret.type)} found at line ${secret.line}" type="${secret.severity}">${escapeXml(secret.snippet)}</failure>\n`;
|
|
185
|
+
}
|
|
186
|
+
xml += ` </testcase>\n`;
|
|
187
|
+
}
|
|
188
|
+
xml += ` </testsuite>
|
|
189
|
+
<testsuite name="Vulnerabilities" tests="${result.packages.length}" failures="${result.packages.filter(p => p.severity === 'critical' || p.severity === 'high').length}">
|
|
190
|
+
`;
|
|
191
|
+
for (const pkg of result.packages) {
|
|
192
|
+
const isFailure = pkg.severity === 'critical' || pkg.severity === 'high';
|
|
193
|
+
xml += ` <testcase name="${escapeXml(pkg.name)}@${escapeXml(pkg.version)}" classname="dependencies">\n`;
|
|
194
|
+
if (isFailure) {
|
|
195
|
+
xml += ` <failure message="${escapeXml(pkg.vulnId || 'vulnerability')}" type="${pkg.severity}">${escapeXml(pkg.title || '')}</failure>\n`;
|
|
196
|
+
}
|
|
197
|
+
xml += ` </testcase>\n`;
|
|
198
|
+
}
|
|
199
|
+
xml += ` </testsuite>
|
|
200
|
+
<testsuite name="IaC" tests="${result.iacFindings.length}" failures="${result.iacFindings.filter(i => i.severity === 'critical' || i.severity === 'high').length}">
|
|
201
|
+
`;
|
|
202
|
+
for (const iac of result.iacFindings) {
|
|
203
|
+
const isFailure = iac.severity === 'critical' || iac.severity === 'high';
|
|
204
|
+
xml += ` <testcase name="${escapeXml(iac.checkId)}" classname="${escapeXml(iac.file)}">\n`;
|
|
205
|
+
if (isFailure) {
|
|
206
|
+
xml += ` <failure message="${escapeXml(iac.title)}" type="${iac.severity}">${escapeXml(iac.guideline || '')}</failure>\n`;
|
|
207
|
+
}
|
|
208
|
+
xml += ` </testcase>\n`;
|
|
209
|
+
}
|
|
210
|
+
xml += ` </testsuite>
|
|
211
|
+
</testsuites>`;
|
|
212
|
+
return xml;
|
|
213
|
+
}
|
|
214
|
+
function escapeXml(str) {
|
|
215
|
+
return str
|
|
216
|
+
.replace(/&/g, '&')
|
|
217
|
+
.replace(/</g, '<')
|
|
218
|
+
.replace(/>/g, '>')
|
|
219
|
+
.replace(/"/g, '"')
|
|
220
|
+
.replace(/'/g, ''');
|
|
221
|
+
}
|
|
222
|
+
function toGitLabSeverity(severity) {
|
|
223
|
+
switch (severity.toLowerCase()) {
|
|
224
|
+
case 'critical': return 'Critical';
|
|
225
|
+
case 'high': return 'High';
|
|
226
|
+
case 'medium': return 'Medium';
|
|
227
|
+
case 'low': return 'Low';
|
|
228
|
+
default: return 'Unknown';
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
export function toGitLabReport(result, reportType) {
|
|
232
|
+
const vulnerabilities = [];
|
|
233
|
+
const startTime = new Date().toISOString();
|
|
234
|
+
if (reportType === 'secret_detection') {
|
|
235
|
+
for (const secret of result.secrets) {
|
|
236
|
+
vulnerabilities.push({
|
|
237
|
+
id: `secret-${Buffer.from(secret.file + secret.line).toString('base64').substring(0, 16)}`,
|
|
238
|
+
category: 'secret_detection',
|
|
239
|
+
name: secret.type,
|
|
240
|
+
message: `${secret.type} detected`,
|
|
241
|
+
description: `Potential secret found in ${secret.file}`,
|
|
242
|
+
severity: toGitLabSeverity(secret.severity),
|
|
243
|
+
confidence: 'High',
|
|
244
|
+
scanner: {
|
|
245
|
+
id: 'aura-security-secrets',
|
|
246
|
+
name: 'AuraSecurity Secret Detection'
|
|
247
|
+
},
|
|
248
|
+
location: {
|
|
249
|
+
file: secret.file,
|
|
250
|
+
start_line: secret.line,
|
|
251
|
+
end_line: secret.line
|
|
252
|
+
},
|
|
253
|
+
identifiers: [{
|
|
254
|
+
type: 'aura_security_secret',
|
|
255
|
+
name: secret.type,
|
|
256
|
+
value: secret.type
|
|
257
|
+
}]
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (reportType === 'dependency_scanning') {
|
|
262
|
+
for (const pkg of result.packages) {
|
|
263
|
+
vulnerabilities.push({
|
|
264
|
+
id: pkg.vulnId || `dep-${Buffer.from(pkg.name + pkg.version).toString('base64').substring(0, 16)}`,
|
|
265
|
+
category: 'dependency_scanning',
|
|
266
|
+
name: pkg.vulnId || `Vulnerability in ${pkg.name}`,
|
|
267
|
+
message: pkg.title || `Security vulnerability in ${pkg.name}`,
|
|
268
|
+
description: `${pkg.name}@${pkg.version} has a known vulnerability`,
|
|
269
|
+
severity: toGitLabSeverity(pkg.severity),
|
|
270
|
+
scanner: {
|
|
271
|
+
id: 'aura-security-deps',
|
|
272
|
+
name: 'AuraSecurity Dependency Scanning'
|
|
273
|
+
},
|
|
274
|
+
location: {
|
|
275
|
+
dependency: {
|
|
276
|
+
package: { name: pkg.name },
|
|
277
|
+
version: pkg.version
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
identifiers: pkg.vulnId ? [{
|
|
281
|
+
type: pkg.vulnId.startsWith('CVE') ? 'cve' : 'ghsa',
|
|
282
|
+
name: pkg.vulnId,
|
|
283
|
+
value: pkg.vulnId,
|
|
284
|
+
url: pkg.vulnId.startsWith('CVE')
|
|
285
|
+
? `https://nvd.nist.gov/vuln/detail/${pkg.vulnId}`
|
|
286
|
+
: `https://github.com/advisories/${pkg.vulnId}`
|
|
287
|
+
}] : [],
|
|
288
|
+
solution: pkg.fixedVersion ? `Upgrade to version ${pkg.fixedVersion}` : undefined
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (reportType === 'sast') {
|
|
293
|
+
for (const sast of result.sastFindings) {
|
|
294
|
+
vulnerabilities.push({
|
|
295
|
+
id: `sast-${Buffer.from(sast.file + sast.line + sast.rule).toString('base64').substring(0, 16)}`,
|
|
296
|
+
category: 'sast',
|
|
297
|
+
name: sast.rule,
|
|
298
|
+
message: sast.message,
|
|
299
|
+
description: sast.message,
|
|
300
|
+
severity: toGitLabSeverity(sast.severity),
|
|
301
|
+
scanner: {
|
|
302
|
+
id: 'aura-security-sast',
|
|
303
|
+
name: 'AuraSecurity SAST'
|
|
304
|
+
},
|
|
305
|
+
location: {
|
|
306
|
+
file: sast.file,
|
|
307
|
+
start_line: sast.line
|
|
308
|
+
},
|
|
309
|
+
identifiers: [{
|
|
310
|
+
type: 'semgrep_rule',
|
|
311
|
+
name: sast.rule,
|
|
312
|
+
value: sast.rule
|
|
313
|
+
}]
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
// Include IaC in SAST report
|
|
317
|
+
for (const iac of result.iacFindings) {
|
|
318
|
+
vulnerabilities.push({
|
|
319
|
+
id: `iac-${Buffer.from(iac.file + iac.checkId).toString('base64').substring(0, 16)}`,
|
|
320
|
+
category: 'sast',
|
|
321
|
+
name: iac.checkId,
|
|
322
|
+
message: iac.title,
|
|
323
|
+
description: iac.guideline || iac.title,
|
|
324
|
+
severity: toGitLabSeverity(iac.severity),
|
|
325
|
+
scanner: {
|
|
326
|
+
id: 'aura-security-iac',
|
|
327
|
+
name: 'AuraSecurity IaC'
|
|
328
|
+
},
|
|
329
|
+
location: {
|
|
330
|
+
file: iac.file
|
|
331
|
+
},
|
|
332
|
+
identifiers: [{
|
|
333
|
+
type: 'checkov_check',
|
|
334
|
+
name: iac.checkId,
|
|
335
|
+
value: iac.checkId
|
|
336
|
+
}],
|
|
337
|
+
solution: iac.guideline
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
version: '15.0.0',
|
|
343
|
+
vulnerabilities,
|
|
344
|
+
scan: {
|
|
345
|
+
analyzer: {
|
|
346
|
+
id: 'aura-security',
|
|
347
|
+
name: 'AuraSecurity',
|
|
348
|
+
version: '0.2.0',
|
|
349
|
+
vendor: { name: 'AuraSecurity' }
|
|
350
|
+
},
|
|
351
|
+
scanner: {
|
|
352
|
+
id: 'aura-security',
|
|
353
|
+
name: 'AuraSecurity',
|
|
354
|
+
version: '0.2.0',
|
|
355
|
+
vendor: { name: 'AuraSecurity' }
|
|
356
|
+
},
|
|
357
|
+
type: reportType,
|
|
358
|
+
start_time: startTime,
|
|
359
|
+
end_time: new Date().toISOString(),
|
|
360
|
+
status: 'success'
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
export function toJSONSummary(result) {
|
|
365
|
+
const critical = result.secrets.filter(s => s.severity === 'critical').length +
|
|
366
|
+
result.packages.filter(p => p.severity === 'critical').length +
|
|
367
|
+
result.iacFindings.filter(i => i.severity === 'critical').length +
|
|
368
|
+
result.dockerfileFindings.filter(d => d.severity === 'critical').length;
|
|
369
|
+
const high = result.secrets.filter(s => s.severity === 'high').length +
|
|
370
|
+
result.packages.filter(p => p.severity === 'high').length +
|
|
371
|
+
result.iacFindings.filter(i => i.severity === 'high').length +
|
|
372
|
+
result.dockerfileFindings.filter(d => d.severity === 'high').length;
|
|
373
|
+
const medium = result.secrets.filter(s => s.severity === 'medium').length +
|
|
374
|
+
result.packages.filter(p => p.severity === 'medium').length +
|
|
375
|
+
result.iacFindings.filter(i => i.severity === 'medium').length +
|
|
376
|
+
result.dockerfileFindings.filter(d => d.severity === 'medium').length;
|
|
377
|
+
const low = result.secrets.filter(s => s.severity === 'low').length +
|
|
378
|
+
result.packages.filter(p => p.severity === 'low').length +
|
|
379
|
+
result.iacFindings.filter(i => i.severity === 'low').length +
|
|
380
|
+
result.dockerfileFindings.filter(d => d.severity === 'low').length;
|
|
381
|
+
const total = critical + high + medium + low;
|
|
382
|
+
return {
|
|
383
|
+
scan: {
|
|
384
|
+
path: result.path,
|
|
385
|
+
timestamp: result.timestamp,
|
|
386
|
+
tools: result.toolsUsed,
|
|
387
|
+
languages: result.languagesDetected
|
|
388
|
+
},
|
|
389
|
+
summary: { total, critical, high, medium, low },
|
|
390
|
+
findings: {
|
|
391
|
+
secrets: result.secrets.length,
|
|
392
|
+
vulnerabilities: result.packages.length,
|
|
393
|
+
sast: result.sastFindings.length,
|
|
394
|
+
iac: result.iacFindings.length,
|
|
395
|
+
dockerfile: result.dockerfileFindings.length
|
|
396
|
+
},
|
|
397
|
+
exitCode: critical > 0 ? 2 : high > 0 ? 1 : 0
|
|
398
|
+
};
|
|
399
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { AuditorInput, AuditEvent, Severity, AssuranceBreak, EvidenceType } from '../types/events.js';
|
|
2
|
+
export interface PipelineContext {
|
|
3
|
+
input: AuditorInput;
|
|
4
|
+
events: AuditEvent[];
|
|
5
|
+
assumptions: string[];
|
|
6
|
+
uncertainties: string[];
|
|
7
|
+
metadata: Map<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface AnalysisStage {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
analyze(ctx: PipelineContext): Promise<void> | void;
|
|
13
|
+
}
|
|
14
|
+
export interface RuleDefinition {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
severity: Severity;
|
|
19
|
+
category: 'secrets' | 'vulnerabilities' | 'compliance' | 'infrastructure' | 'access_control';
|
|
20
|
+
check: (input: AuditorInput) => RuleResult | null;
|
|
21
|
+
}
|
|
22
|
+
export interface RuleResult {
|
|
23
|
+
severity: Severity;
|
|
24
|
+
claim: string;
|
|
25
|
+
attackPath: string[];
|
|
26
|
+
affectedAssets: string[];
|
|
27
|
+
evidenceRefs: Array<{
|
|
28
|
+
type: EvidenceType;
|
|
29
|
+
pointer: string;
|
|
30
|
+
}>;
|
|
31
|
+
assuranceBreak: AssuranceBreak[];
|
|
32
|
+
confidence: number;
|
|
33
|
+
}
|
|
34
|
+
export declare class SecretsDetectionStage implements AnalysisStage {
|
|
35
|
+
name: string;
|
|
36
|
+
description: string;
|
|
37
|
+
private patterns;
|
|
38
|
+
analyze(ctx: PipelineContext): void;
|
|
39
|
+
private createEvent;
|
|
40
|
+
}
|
|
41
|
+
export declare class VulnerabilityScanStage implements AnalysisStage {
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
analyze(ctx: PipelineContext): void;
|
|
45
|
+
private parseVulnScan;
|
|
46
|
+
}
|
|
47
|
+
export declare class CriticalAssetStage implements AnalysisStage {
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
analyze(ctx: PipelineContext): void;
|
|
51
|
+
private adjustSeverity;
|
|
52
|
+
}
|
|
53
|
+
export declare class InfrastructureChangeStage implements AnalysisStage {
|
|
54
|
+
name: string;
|
|
55
|
+
description: string;
|
|
56
|
+
private iacPatterns;
|
|
57
|
+
analyze(ctx: PipelineContext): void;
|
|
58
|
+
}
|
|
59
|
+
export declare class ProductionDeployStage implements AnalysisStage {
|
|
60
|
+
name: string;
|
|
61
|
+
description: string;
|
|
62
|
+
analyze(ctx: PipelineContext): void;
|
|
63
|
+
}
|
|
64
|
+
export declare class SecurityPipeline {
|
|
65
|
+
private stages;
|
|
66
|
+
constructor();
|
|
67
|
+
addStage(stage: AnalysisStage): void;
|
|
68
|
+
removeStage(name: string): void;
|
|
69
|
+
getStages(): AnalysisStage[];
|
|
70
|
+
execute(input: AuditorInput): Promise<PipelineContext>;
|
|
71
|
+
}
|
|
72
|
+
export { PipelineContext as Context, AnalysisStage as Stage, RuleDefinition as Rule };
|