qa360 1.0.4 → 1.1.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/dist/commands/history.js +1 -1
- package/dist/commands/pack.js +1 -1
- package/dist/commands/run.d.ts +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +1 -1
- package/dist/commands/secrets.js +1 -1
- package/dist/commands/serve.js +1 -1
- package/dist/commands/verify.js +1 -1
- package/dist/core/adapters/gitleaks-secrets.d.ts +115 -0
- package/dist/core/adapters/gitleaks-secrets.d.ts.map +1 -0
- package/dist/core/adapters/gitleaks-secrets.js +410 -0
- package/dist/core/adapters/k6-perf.d.ts +86 -0
- package/dist/core/adapters/k6-perf.d.ts.map +1 -0
- package/dist/core/adapters/k6-perf.js +398 -0
- package/dist/core/adapters/osv-deps.d.ts +124 -0
- package/dist/core/adapters/osv-deps.d.ts.map +1 -0
- package/dist/core/adapters/osv-deps.js +372 -0
- package/dist/core/adapters/playwright-api.d.ts +82 -0
- package/dist/core/adapters/playwright-api.d.ts.map +1 -0
- package/dist/core/adapters/playwright-api.js +252 -0
- package/dist/core/adapters/playwright-ui.d.ts +115 -0
- package/dist/core/adapters/playwright-ui.d.ts.map +1 -0
- package/dist/core/adapters/playwright-ui.js +346 -0
- package/dist/core/adapters/semgrep-sast.d.ts +100 -0
- package/dist/core/adapters/semgrep-sast.d.ts.map +1 -0
- package/dist/core/adapters/semgrep-sast.js +322 -0
- package/dist/core/adapters/zap-dast.d.ts +134 -0
- package/dist/core/adapters/zap-dast.d.ts.map +1 -0
- package/dist/core/adapters/zap-dast.js +424 -0
- package/dist/core/hooks/compose.d.ts +62 -0
- package/dist/core/hooks/compose.d.ts.map +1 -0
- package/dist/core/hooks/compose.js +225 -0
- package/dist/core/hooks/runner.d.ts +69 -0
- package/dist/core/hooks/runner.d.ts.map +1 -0
- package/dist/core/hooks/runner.js +303 -0
- package/dist/core/index.d.ts +74 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +39 -0
- package/dist/core/pack/migrator.d.ts +52 -0
- package/dist/core/pack/migrator.d.ts.map +1 -0
- package/dist/core/pack/migrator.js +304 -0
- package/dist/core/pack/validator.d.ts +43 -0
- package/dist/core/pack/validator.d.ts.map +1 -0
- package/dist/core/pack/validator.js +292 -0
- package/dist/core/proof/bundle.d.ts +138 -0
- package/dist/core/proof/bundle.d.ts.map +1 -0
- package/dist/core/proof/bundle.js +160 -0
- package/dist/core/proof/canonicalize.d.ts +48 -0
- package/dist/core/proof/canonicalize.d.ts.map +1 -0
- package/dist/core/proof/canonicalize.js +105 -0
- package/dist/core/proof/index.d.ts +14 -0
- package/dist/core/proof/index.d.ts.map +1 -0
- package/dist/core/proof/index.js +18 -0
- package/dist/core/proof/schema.d.ts +218 -0
- package/dist/core/proof/schema.d.ts.map +1 -0
- package/dist/core/proof/schema.js +263 -0
- package/dist/core/proof/signer.d.ts +112 -0
- package/dist/core/proof/signer.d.ts.map +1 -0
- package/dist/core/proof/signer.js +226 -0
- package/dist/core/proof/verifier.d.ts +98 -0
- package/dist/core/proof/verifier.d.ts.map +1 -0
- package/dist/core/proof/verifier.js +302 -0
- package/dist/core/runner/phase3-runner.d.ts +102 -0
- package/dist/core/runner/phase3-runner.d.ts.map +1 -0
- package/dist/core/runner/phase3-runner.js +471 -0
- package/dist/core/secrets/crypto.d.ts +76 -0
- package/dist/core/secrets/crypto.d.ts.map +1 -0
- package/dist/core/secrets/crypto.js +225 -0
- package/dist/core/secrets/manager.d.ts +77 -0
- package/dist/core/secrets/manager.d.ts.map +1 -0
- package/dist/core/secrets/manager.js +219 -0
- package/dist/core/security/redaction-patterns-extended.d.ts +28 -0
- package/dist/core/security/redaction-patterns-extended.d.ts.map +1 -0
- package/dist/core/security/redaction-patterns-extended.js +247 -0
- package/dist/core/security/redactor.d.ts +72 -0
- package/dist/core/security/redactor.d.ts.map +1 -0
- package/dist/core/security/redactor.js +279 -0
- package/dist/core/serve/diagnostics-collector.d.ts +33 -0
- package/dist/core/serve/diagnostics-collector.d.ts.map +1 -0
- package/dist/core/serve/diagnostics-collector.js +149 -0
- package/dist/core/serve/health-checker.d.ts +45 -0
- package/dist/core/serve/health-checker.d.ts.map +1 -0
- package/dist/core/serve/health-checker.js +219 -0
- package/dist/core/serve/index.d.ts +9 -0
- package/dist/core/serve/index.d.ts.map +1 -0
- package/dist/core/serve/index.js +8 -0
- package/dist/core/serve/metrics-collector.d.ts +25 -0
- package/dist/core/serve/metrics-collector.d.ts.map +1 -0
- package/dist/core/serve/metrics-collector.js +322 -0
- package/dist/core/serve/process-manager.d.ts +37 -0
- package/dist/core/serve/process-manager.d.ts.map +1 -0
- package/dist/core/serve/process-manager.js +213 -0
- package/dist/core/serve/server.d.ts +37 -0
- package/dist/core/serve/server.d.ts.map +1 -0
- package/dist/core/serve/server.js +191 -0
- package/dist/core/types/pack-v1.d.ts +162 -0
- package/dist/core/types/pack-v1.d.ts.map +1 -0
- package/dist/core/types/pack-v1.js +5 -0
- package/dist/core/types/trust-score.d.ts +70 -0
- package/dist/core/types/trust-score.d.ts.map +1 -0
- package/dist/core/types/trust-score.js +191 -0
- package/dist/core/vault/cas.d.ts +87 -0
- package/dist/core/vault/cas.d.ts.map +1 -0
- package/dist/core/vault/cas.js +255 -0
- package/dist/core/vault/index.d.ts +205 -0
- package/dist/core/vault/index.d.ts.map +1 -0
- package/dist/core/vault/index.js +631 -0
- package/package.json +13 -6
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 Semgrep SAST Adapter (Socle OOTB)
|
|
3
|
+
* Static Application Security Testing with configurable severity thresholds
|
|
4
|
+
*/
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { existsSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { SecurityRedactor } from '../security/redactor.js';
|
|
9
|
+
export class SemgrepSastAdapter {
|
|
10
|
+
redactor;
|
|
11
|
+
constructor() {
|
|
12
|
+
this.redactor = SecurityRedactor.forLogs();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Execute Semgrep SAST scan
|
|
16
|
+
*/
|
|
17
|
+
async runSastScan(config) {
|
|
18
|
+
try {
|
|
19
|
+
console.log(`🔍 Running Semgrep SAST scan (${config.paths?.join(', ') || 'default paths'})`);
|
|
20
|
+
// Check if Semgrep is available
|
|
21
|
+
const availability = await SemgrepSastAdapter.isAvailable();
|
|
22
|
+
if (!availability.available) {
|
|
23
|
+
return {
|
|
24
|
+
success: false,
|
|
25
|
+
findings: [],
|
|
26
|
+
summary: this.getDefaultSummary(),
|
|
27
|
+
thresholds: this.getDefaultThresholds(config.security),
|
|
28
|
+
error: availability.error
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Execute Semgrep
|
|
32
|
+
const result = await this.executeSemgrep(config);
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
findings: [],
|
|
39
|
+
summary: this.getDefaultSummary(),
|
|
40
|
+
thresholds: this.getDefaultThresholds(config.security),
|
|
41
|
+
error: this.redactor.redact(error instanceof Error ? error.message : 'Unknown error')
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Execute Semgrep command
|
|
47
|
+
*/
|
|
48
|
+
async executeSemgrep(config) {
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
|
+
let output = '';
|
|
51
|
+
let error = '';
|
|
52
|
+
const rules = config.rules || ['auto'];
|
|
53
|
+
const paths = config.paths || ['.'];
|
|
54
|
+
const args = [
|
|
55
|
+
'--config', rules.join(','),
|
|
56
|
+
'--json',
|
|
57
|
+
'--no-git-ignore', // Include all files
|
|
58
|
+
'--timeout', '60',
|
|
59
|
+
...paths
|
|
60
|
+
];
|
|
61
|
+
// Add custom config if specified
|
|
62
|
+
if (config.configFile && existsSync(join(config.workingDir, config.configFile))) {
|
|
63
|
+
args.unshift('--config', config.configFile);
|
|
64
|
+
}
|
|
65
|
+
const child = spawn('semgrep', args, {
|
|
66
|
+
cwd: config.workingDir,
|
|
67
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
68
|
+
});
|
|
69
|
+
const timeout = setTimeout(() => {
|
|
70
|
+
child.kill('SIGKILL');
|
|
71
|
+
resolve({
|
|
72
|
+
success: false,
|
|
73
|
+
findings: [],
|
|
74
|
+
summary: this.getDefaultSummary(),
|
|
75
|
+
thresholds: this.getDefaultThresholds(config.security),
|
|
76
|
+
error: `Semgrep scan timed out after ${config.timeout || 120000}ms`
|
|
77
|
+
});
|
|
78
|
+
}, config.timeout || 120000);
|
|
79
|
+
if (child.stdout) {
|
|
80
|
+
child.stdout.on('data', (data) => {
|
|
81
|
+
output += data.toString();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (child.stderr) {
|
|
85
|
+
child.stderr.on('data', (data) => {
|
|
86
|
+
error += data.toString();
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
child.on('close', (code) => {
|
|
90
|
+
clearTimeout(timeout);
|
|
91
|
+
// Semgrep returns 0 for no findings, 1 for findings, 2+ for errors
|
|
92
|
+
if (code === 0 || code === 1) {
|
|
93
|
+
const result = this.parseSemgrepResults(output, config);
|
|
94
|
+
resolve(result);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
resolve({
|
|
98
|
+
success: false,
|
|
99
|
+
findings: [],
|
|
100
|
+
summary: this.getDefaultSummary(),
|
|
101
|
+
thresholds: this.getDefaultThresholds(config.security),
|
|
102
|
+
error: this.redactor.redact(error || `Semgrep exited with code ${code}`),
|
|
103
|
+
rawOutput: this.redactor.redact(output)
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
child.on('error', (err) => {
|
|
108
|
+
clearTimeout(timeout);
|
|
109
|
+
resolve({
|
|
110
|
+
success: false,
|
|
111
|
+
findings: [],
|
|
112
|
+
summary: this.getDefaultSummary(),
|
|
113
|
+
thresholds: this.getDefaultThresholds(config.security),
|
|
114
|
+
error: `Failed to start Semgrep: ${err.message}`
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse Semgrep JSON results
|
|
121
|
+
*/
|
|
122
|
+
parseSemgrepResults(output, config) {
|
|
123
|
+
try {
|
|
124
|
+
const jsonData = JSON.parse(output);
|
|
125
|
+
const findings = [];
|
|
126
|
+
// Parse findings from results
|
|
127
|
+
if (jsonData.results && Array.isArray(jsonData.results)) {
|
|
128
|
+
for (const result of jsonData.results) {
|
|
129
|
+
const finding = {
|
|
130
|
+
ruleId: result.check_id || 'unknown',
|
|
131
|
+
severity: this.mapSeverity(result.extra?.severity || 'INFO'),
|
|
132
|
+
message: result.extra?.message || result.message || 'Security issue detected',
|
|
133
|
+
file: result.path || 'unknown',
|
|
134
|
+
line: result.start?.line || 0,
|
|
135
|
+
column: result.start?.col || 0,
|
|
136
|
+
code: result.extra?.lines ? result.extra.lines.trim() : undefined,
|
|
137
|
+
fix: result.extra?.fix ? result.extra.fix.trim() : undefined
|
|
138
|
+
};
|
|
139
|
+
findings.push(finding);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Calculate summary
|
|
143
|
+
const summary = this.calculateSummary(findings);
|
|
144
|
+
// Check thresholds
|
|
145
|
+
const thresholds = this.checkThresholds(summary, config.security);
|
|
146
|
+
// Determine success based on thresholds
|
|
147
|
+
const success = thresholds.sast_max_high.passed;
|
|
148
|
+
const junit = this.generateJUnit(findings, success);
|
|
149
|
+
return {
|
|
150
|
+
success,
|
|
151
|
+
findings: findings.map(f => ({
|
|
152
|
+
...f,
|
|
153
|
+
message: this.redactor.redact(f.message),
|
|
154
|
+
code: f.code ? this.redactor.redact(f.code) : undefined,
|
|
155
|
+
fix: f.fix ? this.redactor.redact(f.fix) : undefined
|
|
156
|
+
})),
|
|
157
|
+
summary,
|
|
158
|
+
thresholds,
|
|
159
|
+
rawOutput: this.redactor.redact(output),
|
|
160
|
+
junit
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
return {
|
|
165
|
+
success: false,
|
|
166
|
+
findings: [],
|
|
167
|
+
summary: this.getDefaultSummary(),
|
|
168
|
+
thresholds: this.getDefaultThresholds(config.security),
|
|
169
|
+
error: `Failed to parse Semgrep results: ${error}`,
|
|
170
|
+
rawOutput: this.redactor.redact(output)
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Map Semgrep severity to standard levels
|
|
176
|
+
*/
|
|
177
|
+
mapSeverity(severity) {
|
|
178
|
+
const sev = severity.toUpperCase();
|
|
179
|
+
if (sev === 'ERROR' || sev === 'HIGH')
|
|
180
|
+
return 'ERROR';
|
|
181
|
+
if (sev === 'WARNING' || sev === 'MEDIUM')
|
|
182
|
+
return 'WARNING';
|
|
183
|
+
return 'INFO';
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Calculate findings summary
|
|
187
|
+
*/
|
|
188
|
+
calculateSummary(findings) {
|
|
189
|
+
const summary = {
|
|
190
|
+
total: findings.length,
|
|
191
|
+
critical: 0,
|
|
192
|
+
high: 0,
|
|
193
|
+
medium: 0,
|
|
194
|
+
low: 0,
|
|
195
|
+
info: 0
|
|
196
|
+
};
|
|
197
|
+
for (const finding of findings) {
|
|
198
|
+
switch (finding.severity) {
|
|
199
|
+
case 'ERROR':
|
|
200
|
+
summary.high++;
|
|
201
|
+
break;
|
|
202
|
+
case 'WARNING':
|
|
203
|
+
summary.medium++;
|
|
204
|
+
break;
|
|
205
|
+
case 'INFO':
|
|
206
|
+
summary.info++;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return summary;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check security thresholds
|
|
214
|
+
*/
|
|
215
|
+
checkThresholds(summary, security) {
|
|
216
|
+
const maxHigh = security?.sast?.max_high ?? 0; // Default: strict (0 high findings)
|
|
217
|
+
return {
|
|
218
|
+
sast_max_high: {
|
|
219
|
+
passed: summary.high <= maxHigh,
|
|
220
|
+
actual: summary.high,
|
|
221
|
+
budget: maxHigh
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Generate JUnit XML
|
|
227
|
+
*/
|
|
228
|
+
generateJUnit(findings, success) {
|
|
229
|
+
const timestamp = new Date().toISOString();
|
|
230
|
+
const failures = findings.filter(f => f.severity === 'ERROR').length;
|
|
231
|
+
let junit = `<?xml version="1.0" encoding="UTF-8"?>
|
|
232
|
+
<testsuite name="Semgrep SAST Scan" tests="1" failures="${success ? 0 : 1}" time="0" timestamp="${timestamp}">
|
|
233
|
+
<testcase name="SAST Security Scan" time="0">
|
|
234
|
+
`;
|
|
235
|
+
if (!success) {
|
|
236
|
+
junit += ` <failure message="Security issues found">
|
|
237
|
+
High severity findings: ${findings.filter(f => f.severity === 'ERROR').length}
|
|
238
|
+
Medium severity findings: ${findings.filter(f => f.severity === 'WARNING').length}
|
|
239
|
+
Total findings: ${findings.length}
|
|
240
|
+
|
|
241
|
+
Top findings:
|
|
242
|
+
${findings.slice(0, 5).map(f => `- ${f.ruleId}: ${f.message} (${f.file}:${f.line})`).join('\n')}
|
|
243
|
+
</failure>
|
|
244
|
+
`;
|
|
245
|
+
}
|
|
246
|
+
junit += ` </testcase>
|
|
247
|
+
</testsuite>`;
|
|
248
|
+
return junit;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get default summary structure
|
|
252
|
+
*/
|
|
253
|
+
getDefaultSummary() {
|
|
254
|
+
return {
|
|
255
|
+
total: 0,
|
|
256
|
+
critical: 0,
|
|
257
|
+
high: 0,
|
|
258
|
+
medium: 0,
|
|
259
|
+
low: 0,
|
|
260
|
+
info: 0
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Get default thresholds
|
|
265
|
+
*/
|
|
266
|
+
getDefaultThresholds(security) {
|
|
267
|
+
return {
|
|
268
|
+
sast_max_high: {
|
|
269
|
+
passed: true,
|
|
270
|
+
actual: 0,
|
|
271
|
+
budget: security?.sast?.max_high ?? 0
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Check if Semgrep is available
|
|
277
|
+
*/
|
|
278
|
+
static async isAvailable() {
|
|
279
|
+
return new Promise((resolve) => {
|
|
280
|
+
const child = spawn('semgrep', ['--version'], { stdio: 'pipe' });
|
|
281
|
+
child.on('close', (code) => {
|
|
282
|
+
resolve({
|
|
283
|
+
available: code === 0,
|
|
284
|
+
error: code !== 0 ? 'Semgrep not found. Install with: pip install semgrep' : undefined
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
child.on('error', () => {
|
|
288
|
+
resolve({
|
|
289
|
+
available: false,
|
|
290
|
+
error: 'Semgrep not found. Install with: pip install semgrep'
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Validate SAST configuration
|
|
297
|
+
*/
|
|
298
|
+
static validateConfig(config) {
|
|
299
|
+
const errors = [];
|
|
300
|
+
if (!config.workingDir || !existsSync(config.workingDir)) {
|
|
301
|
+
errors.push('SAST scan requires valid working directory');
|
|
302
|
+
}
|
|
303
|
+
if (config.paths) {
|
|
304
|
+
for (const path of config.paths) {
|
|
305
|
+
const fullPath = join(config.workingDir, path);
|
|
306
|
+
if (!existsSync(fullPath)) {
|
|
307
|
+
errors.push(`SAST scan path not found: ${path}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (config.configFile) {
|
|
312
|
+
const configPath = join(config.workingDir, config.configFile);
|
|
313
|
+
if (!existsSync(configPath)) {
|
|
314
|
+
errors.push(`Semgrep config file not found: ${config.configFile}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
valid: errors.length === 0,
|
|
319
|
+
errors
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 ZAP DAST Adapter (Sécurité Réelle)
|
|
3
|
+
* OWASP ZAP baseline scan for dynamic application security testing
|
|
4
|
+
*/
|
|
5
|
+
import { PackSecurity } from '../types/pack-v1.js';
|
|
6
|
+
export interface ZapDastConfig {
|
|
7
|
+
targetUrl: string;
|
|
8
|
+
security?: PackSecurity;
|
|
9
|
+
timeout?: number;
|
|
10
|
+
scanType?: 'baseline' | 'full' | 'api';
|
|
11
|
+
contextFile?: string;
|
|
12
|
+
excludeUrls?: string[];
|
|
13
|
+
includeUrls?: string[];
|
|
14
|
+
authScript?: string;
|
|
15
|
+
configFile?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ZapAlert {
|
|
18
|
+
pluginid: string;
|
|
19
|
+
alertRef: string;
|
|
20
|
+
alert: string;
|
|
21
|
+
name: string;
|
|
22
|
+
riskcode: string;
|
|
23
|
+
confidence: string;
|
|
24
|
+
riskdesc: string;
|
|
25
|
+
desc: string;
|
|
26
|
+
instances: Array<{
|
|
27
|
+
uri: string;
|
|
28
|
+
method: string;
|
|
29
|
+
param: string;
|
|
30
|
+
attack: string;
|
|
31
|
+
evidence: string;
|
|
32
|
+
otherinfo: string;
|
|
33
|
+
}>;
|
|
34
|
+
count: string;
|
|
35
|
+
solution: string;
|
|
36
|
+
otherinfo: string;
|
|
37
|
+
reference: string;
|
|
38
|
+
cweid: string;
|
|
39
|
+
wascid: string;
|
|
40
|
+
sourceid: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ZapDastResult {
|
|
43
|
+
success: boolean;
|
|
44
|
+
alerts: ZapAlert[];
|
|
45
|
+
summary: {
|
|
46
|
+
total: number;
|
|
47
|
+
high: number;
|
|
48
|
+
medium: number;
|
|
49
|
+
low: number;
|
|
50
|
+
informational: number;
|
|
51
|
+
by_category: Record<string, number>;
|
|
52
|
+
};
|
|
53
|
+
budgetCheck: {
|
|
54
|
+
high_passed: boolean;
|
|
55
|
+
critical_passed: boolean;
|
|
56
|
+
medium_passed: boolean;
|
|
57
|
+
};
|
|
58
|
+
targetUrl: string;
|
|
59
|
+
scanDuration: number;
|
|
60
|
+
error?: string;
|
|
61
|
+
rawOutput?: string;
|
|
62
|
+
reportPath?: string;
|
|
63
|
+
junit?: string;
|
|
64
|
+
errorCode?: string;
|
|
65
|
+
}
|
|
66
|
+
export declare class ZapDastAdapter {
|
|
67
|
+
private redactor;
|
|
68
|
+
private workingDir;
|
|
69
|
+
constructor(workingDir?: string);
|
|
70
|
+
/**
|
|
71
|
+
* Execute ZAP DAST scan
|
|
72
|
+
*/
|
|
73
|
+
runDastScan(config: ZapDastConfig): Promise<ZapDastResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Validate URL format
|
|
76
|
+
*/
|
|
77
|
+
private isValidUrl;
|
|
78
|
+
/**
|
|
79
|
+
* Execute ZAP scanner
|
|
80
|
+
*/
|
|
81
|
+
private executeZapScan;
|
|
82
|
+
/**
|
|
83
|
+
* Check if Docker should be used for ZAP
|
|
84
|
+
*/
|
|
85
|
+
private shouldUseDocker;
|
|
86
|
+
/**
|
|
87
|
+
* Build ZAP command arguments
|
|
88
|
+
*/
|
|
89
|
+
private buildZapArgs;
|
|
90
|
+
/**
|
|
91
|
+
* Parse ZAP scan results
|
|
92
|
+
*/
|
|
93
|
+
private parseZapResults;
|
|
94
|
+
/**
|
|
95
|
+
* Fallback mock scan when ZAP not available
|
|
96
|
+
*/
|
|
97
|
+
private fallbackMockScan;
|
|
98
|
+
/**
|
|
99
|
+
* Calculate alerts summary
|
|
100
|
+
*/
|
|
101
|
+
private calculateSummary;
|
|
102
|
+
/**
|
|
103
|
+
* Generate budget check based on security config
|
|
104
|
+
*/
|
|
105
|
+
private generateBudgetCheck;
|
|
106
|
+
/**
|
|
107
|
+
* Get empty summary structure
|
|
108
|
+
*/
|
|
109
|
+
private getEmptySummary;
|
|
110
|
+
/**
|
|
111
|
+
* Get default budget check structure
|
|
112
|
+
*/
|
|
113
|
+
private getDefaultBudgetCheck;
|
|
114
|
+
/**
|
|
115
|
+
* Generate JUnit XML report
|
|
116
|
+
*/
|
|
117
|
+
private generateJUnit;
|
|
118
|
+
/**
|
|
119
|
+
* Validate ZAP scan configuration
|
|
120
|
+
*/
|
|
121
|
+
static validateConfig(config: ZapDastConfig): {
|
|
122
|
+
valid: boolean;
|
|
123
|
+
errors: string[];
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Check if ZAP is available (Docker or local)
|
|
127
|
+
*/
|
|
128
|
+
static isAvailable(): Promise<{
|
|
129
|
+
available: boolean;
|
|
130
|
+
method?: 'docker' | 'local';
|
|
131
|
+
error?: string;
|
|
132
|
+
}>;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=zap-dast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zap-dast.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/zap-dast.ts"],"names":[],"mappings":"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"}
|