Skip to content

Commit 8789eb2

Browse files
authored
Merge pull request #15 from quantumdark/severity-scope
feat: Add SEVERITY_CHECK_SCOPE parameter to control the blocking scope
2 parents a7f51a2 + 954688c commit 8789eb2

3 files changed

Lines changed: 74 additions & 19 deletions

File tree

action.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ inputs:
7272
description: >
7373
When enabled, waits for the static_scan to be COMPLETED instead of the top-level scan. Default is false.
7474
required: false
75+
SEVERITY_CHECK_SCOPE:
76+
description: >
77+
Controls whether BLOCK_ON_SEVERITY and WARN_ON_SEVERITY check only findings
78+
from the current scan or all open findings in the mobile app.
79+
Valid values: CURRENT_SCAN, ALL_ISSUES
80+
- CURRENT_SCAN: Check only findings discovered in the current scan (default)
81+
- ALL_ISSUES: Check all open findings associated with the mobile app
82+
Default: CURRENT_SCAN
83+
required: false
84+
default: 'CURRENT_SCAN'
7585
runs:
7686
using: 'node20'
7787
main: 'main.js'

main.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ function get_security_findings(dt_results_api_key, mobile_app_id, results_since,
4545
const baseUrl = "https://api.securetheorem.com/apis/mobile_security/results/v2/security_findings";
4646
const params = new URLSearchParams({
4747
mobile_app_id,
48-
results_since,
4948
status_group: "OPEN",
5049
});
50+
if (results_since) {
51+
params.append("results_since", results_since);
52+
}
5153
if (severity) {
5254
params.append("severity", severity);
5355
}
@@ -61,7 +63,7 @@ function get_security_findings(dt_results_api_key, mobile_app_id, results_since,
6163
});
6264
});
6365
}
64-
function check_severity_findings(dt_results_api_key, mobile_app_id, results_since, severity_level) {
66+
function check_severity_findings(dt_results_api_key, mobile_app_id, results_since, severity_level, check_scope) {
6567
return __awaiter(this, void 0, void 0, function* () {
6668
const severity_checks = {
6769
HIGH: ["HIGH"],
@@ -73,8 +75,10 @@ function check_severity_findings(dt_results_api_key, mobile_app_id, results_sinc
7375
throw new Error(`Invalid severity level: ${severity_level}`);
7476
}
7577
let total_findings = 0;
78+
// Determine which results_since to use based on scope
79+
const effective_results_since = check_scope.toUpperCase() === "ALL_ISSUES" ? null : results_since;
7680
for (const severity of severities_to_check) {
77-
const findings_response = yield get_security_findings(dt_results_api_key, mobile_app_id, results_since, severity);
81+
const findings_response = yield get_security_findings(dt_results_api_key, mobile_app_id, effective_results_since, severity);
7882
if (findings_response.status !== 200) {
7983
throw new Error(`Error fetching security findings for ${severity} severity: HTTP ${findings_response.status}`);
8084
}
@@ -108,6 +112,7 @@ function run() {
108112
const warn_on_severity = core.getInput("WARN_ON_SEVERITY");
109113
const polling_timeout = core.getInput("POLLING_TIMEOUT");
110114
const wait_for_static_scan_only = core.getInput("WAIT_FOR_STATIC_SCAN_ONLY");
115+
const severity_check_scope = core.getInput("SEVERITY_CHECK_SCOPE") || "CURRENT_SCAN";
111116
var parsed_polling_timeout;
112117
if (polling_timeout) {
113118
parsed_polling_timeout = parseInt(polling_timeout, 10);
@@ -127,6 +132,9 @@ function run() {
127132
!["HIGH", "MEDIUM", "LOW"].includes(warn_on_severity.toUpperCase())) {
128133
throw new Error("WARN_ON_SEVERITY must be one of: HIGH, MEDIUM, LOW");
129134
}
135+
if (!["CURRENT_SCAN", "ALL_ISSUES"].includes(severity_check_scope.toUpperCase())) {
136+
throw new Error("SEVERITY_CHECK_SCOPE must be one of: CURRENT_SCAN, ALL_ISSUES");
137+
}
130138
// Mask the sensitive fields
131139
core.setSecret(dt_upload_api_key);
132140
core.setSecret(dt_results_api_key);
@@ -330,13 +338,19 @@ function run() {
330338
// Check for blocking vulnerabilities first
331339
if (block_on_severity) {
332340
try {
333-
const { has_findings, total_count } = yield check_severity_findings(dt_results_api_key, mobile_app_id, results_since, block_on_severity);
341+
const { has_findings, total_count } = yield check_severity_findings(dt_results_api_key, mobile_app_id, results_since, block_on_severity, severity_check_scope);
334342
if (has_findings) {
335-
console.log(`Found ${total_count} security findings at or above ${block_on_severity} severity level`);
336-
core.setFailed(`Build blocked due to ${total_count} security findings at or above ${block_on_severity} severity level`);
343+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
344+
? "in the mobile app"
345+
: "in this scan";
346+
console.log(`Found ${total_count} security findings ${scope_description} at or above ${block_on_severity} severity level`);
347+
core.setFailed(`Build blocked due to ${total_count} security findings ${scope_description} at or above ${block_on_severity} severity level`);
337348
return;
338349
}
339-
console.log(`No security findings found at or above ${block_on_severity} severity level for scan ${scan_id}`);
350+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
351+
? "in the mobile app"
352+
: `for scan ${scan_id}`;
353+
console.log(`No security findings found at or above ${block_on_severity} severity level ${scope_description}`);
340354
}
341355
catch (error) {
342356
console.log(`Error checking security findings for scan ${scan_id}: ${error.message}`);
@@ -346,13 +360,19 @@ function run() {
346360
// Check for warning vulnerabilities
347361
if (warn_on_severity) {
348362
try {
349-
const { has_findings, total_count } = yield check_severity_findings(dt_results_api_key, mobile_app_id, results_since, warn_on_severity);
363+
const { has_findings, total_count } = yield check_severity_findings(dt_results_api_key, mobile_app_id, results_since, warn_on_severity, severity_check_scope);
350364
if (has_findings) {
351-
console.log(`⚠️ WARNING: Found ${total_count} security findings at or above ${warn_on_severity} severity level for scan ${scan_id}`);
365+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
366+
? "in the mobile app"
367+
: `for scan ${scan_id}`;
368+
console.log(`⚠️ WARNING: Found ${total_count} security findings ${scope_description} at or above ${warn_on_severity} severity level`);
352369
console.log(`⚠️ These findings do not block the build, but should be reviewed and addressed.`);
353370
}
354371
else {
355-
console.log(`No security findings found at or above ${warn_on_severity} severity level for scan ${scan_id}`);
372+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
373+
? "in the mobile app"
374+
: `for scan ${scan_id}`;
375+
console.log(`No security findings found at or above ${warn_on_severity} severity level ${scope_description}`);
356376
}
357377
}
358378
catch (error) {

main.ts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,19 @@ async function check_scan_status(
3939
async function get_security_findings(
4040
dt_results_api_key: string,
4141
mobile_app_id: string,
42-
results_since: string,
42+
results_since: string | null,
4343
severity?: string,
4444
): Promise<Response> {
4545
const baseUrl = "https://api.securetheorem.com/apis/mobile_security/results/v2/security_findings";
4646
const params = new URLSearchParams({
4747
mobile_app_id,
48-
results_since,
4948
status_group: "OPEN",
5049
});
51-
50+
51+
if (results_since) {
52+
params.append("results_since", results_since);
53+
}
54+
5255
if (severity) {
5356
params.append("severity", severity);
5457
}
@@ -68,6 +71,7 @@ async function check_severity_findings(
6871
mobile_app_id: string,
6972
results_since: string,
7073
severity_level: string,
74+
check_scope: string,
7175
): Promise<{ has_findings: boolean; total_count: number }> {
7276
const severity_checks = {
7377
HIGH: ["HIGH"],
@@ -82,11 +86,14 @@ async function check_severity_findings(
8286

8387
let total_findings = 0;
8488

89+
// Determine which results_since to use based on scope
90+
const effective_results_since = check_scope.toUpperCase() === "ALL_ISSUES" ? null : results_since;
91+
8592
for (const severity of severities_to_check) {
8693
const findings_response = await get_security_findings(
8794
dt_results_api_key,
8895
mobile_app_id,
89-
results_since,
96+
effective_results_since,
9097
severity,
9198
);
9299

@@ -127,6 +134,7 @@ async function run() {
127134
const warn_on_severity = core.getInput("WARN_ON_SEVERITY");
128135
const polling_timeout = core.getInput("POLLING_TIMEOUT");
129136
const wait_for_static_scan_only = core.getInput("WAIT_FOR_STATIC_SCAN_ONLY");
137+
const severity_check_scope = core.getInput("SEVERITY_CHECK_SCOPE") || "CURRENT_SCAN";
130138
var parsed_polling_timeout;
131139
if (polling_timeout) {
132140
parsed_polling_timeout = parseInt(polling_timeout, 10);
@@ -151,6 +159,9 @@ async function run() {
151159
) {
152160
throw new Error("WARN_ON_SEVERITY must be one of: HIGH, MEDIUM, LOW");
153161
}
162+
if (!["CURRENT_SCAN", "ALL_ISSUES"].includes(severity_check_scope.toUpperCase())) {
163+
throw new Error("SEVERITY_CHECK_SCOPE must be one of: CURRENT_SCAN, ALL_ISSUES");
164+
}
154165

155166
// Mask the sensitive fields
156167
core.setSecret(dt_upload_api_key);
@@ -414,20 +425,27 @@ async function run() {
414425
mobile_app_id,
415426
results_since,
416427
block_on_severity,
428+
severity_check_scope,
417429
);
418430

419431
if (has_findings) {
432+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
433+
? "in the mobile app"
434+
: "in this scan";
420435
console.log(
421-
`Found ${total_count} security findings at or above ${block_on_severity} severity level`,
436+
`Found ${total_count} security findings ${scope_description} at or above ${block_on_severity} severity level`,
422437
);
423438
core.setFailed(
424-
`Build blocked due to ${total_count} security findings at or above ${block_on_severity} severity level`,
439+
`Build blocked due to ${total_count} security findings ${scope_description} at or above ${block_on_severity} severity level`,
425440
);
426441
return;
427442
}
428443

444+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
445+
? "in the mobile app"
446+
: `for scan ${scan_id}`;
429447
console.log(
430-
`No security findings found at or above ${block_on_severity} severity level for scan ${scan_id}`,
448+
`No security findings found at or above ${block_on_severity} severity level ${scope_description}`,
431449
);
432450
} catch (error) {
433451
console.log(
@@ -445,18 +463,25 @@ async function run() {
445463
mobile_app_id,
446464
results_since,
447465
warn_on_severity,
466+
severity_check_scope,
448467
);
449468

450469
if (has_findings) {
470+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
471+
? "in the mobile app"
472+
: `for scan ${scan_id}`;
451473
console.log(
452-
`⚠️ WARNING: Found ${total_count} security findings at or above ${warn_on_severity} severity level for scan ${scan_id}`,
474+
`⚠️ WARNING: Found ${total_count} security findings ${scope_description} at or above ${warn_on_severity} severity level`,
453475
);
454476
console.log(
455477
`⚠️ These findings do not block the build, but should be reviewed and addressed.`,
456478
);
457479
} else {
480+
const scope_description = severity_check_scope.toUpperCase() === "ALL_ISSUES"
481+
? "in the mobile app"
482+
: `for scan ${scan_id}`;
458483
console.log(
459-
`No security findings found at or above ${warn_on_severity} severity level for scan ${scan_id}`,
484+
`No security findings found at or above ${warn_on_severity} severity level ${scope_description}`,
460485
);
461486
}
462487
} catch (error) {

0 commit comments

Comments
 (0)