Skip to content

Commit db13078

Browse files
committed
feat(hdf-converters): add Semgrep JSON to HDF mapper
Semgrep's native JSON carries a rule metadata layer that its SARIF output drops: impact and likelihood, the ASVS control mapping, reference URLs, vulnerability_class, technology and subcategory, and the bandit rule cross-reference. SARIF keeps CWE, OWASP and confidence only as untyped prose tags on the rule object. Converting the native format preserves the cross-framework links that make the results usable for accreditation. One control per rule: Semgrep metadata is rule-scoped and identical across occurrences, so findings collapse into results under a single control keyed on check_id. Notes on the format, all confirmed against semgrep 1.174.0 output rather than its documentation: - metadata fields documented as arrays arrive as bare strings when a rule declares a single value (owasp, subcategory, technology); everything list-shaped is normalized on read - CWEs are emitted in prose form ('CWE-89: Improper Neutralization of ...'), so the id is parsed out before the NIST lookup - extra.lines and extra.fingerprint are redacted to the literal string 'requires login' in unauthenticated scans and are filtered rather than mapped - metadata.impact rates the severity of the consequence and is not HDF's impact float; it is tagged as semgrep_impact so it cannot shadow it - findings suppressed with a nosemgrep comment are omitted from the output entirely rather than flagged, so no skipped status is derivable - extra.fix is replacement text for the matched span, not a standalone instruction, and is labelled accordingly Scan errors become their own control with status error, present only when the scan produced any, so a file that failed to parse is visible rather than buried in passthrough. The fingerprint keys on semgrep-specific paths (paths.scanned, engine_requested, skipped_rules) rather than the generic results/errors/ version triple, which matched bare arrays of HDF controls belonging to other converters. Also normalizes quoting on the adjacent CHECKOV fingerprint line to satisfy the repository prettier configuration. Signed-off-by: clem-field <kc8yhe@me.com>
1 parent 2e4a8be commit db13078

13 files changed

Lines changed: 1943 additions & 8 deletions

File tree

apps/frontend/src/store/report_intake.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
NiktoMapper,
3030
PrismaMapper,
3131
SarifMapper,
32+
SemgrepMapper,
3233
ScoutsuiteMapper,
3334
SnykResults,
3435
TrufflehogResults,
@@ -246,6 +247,8 @@ export class InspecIntake extends VuexModule {
246247
return new NiktoMapper(convertOptions.data).toHdf();
247248
case INPUT_TYPES.SARIF:
248249
return new SarifMapper(convertOptions.data).toHdf();
250+
case INPUT_TYPES.SEMGREP:
251+
return new SemgrepMapper(convertOptions.data).toHdf();
249252
case INPUT_TYPES.SNYK:
250253
return new SnykResults(convertOptions.data).toHdf();
251254
case INPUT_TYPES.TWISTLOCK:

libs/hdf-converters/README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ OHDF Converters supplies several methods to convert various types of security to
2929
21. [**prisma-mapper**] - Prisma Cloud Scan Report CSV file
3030
22. [**sarif-mapper**] - SARIF JSON file
3131
23. [**scoutsuite-mapper**] - ScoutSuite results from a Javascript object
32-
24. [**snyk-mapper**] - Snyk results JSON file
33-
25. [**sonarqube-mapper**] - SonarQube vulnerabilities for the specified project name and optional branch or pull/merge request ID name from an API
34-
26. [**splunk-mapper**] - Splunk instance
35-
27. [**trufflehog-mapper**] - Trufflehog results json file
36-
28. [**twistlock-mapper**] - Twistlock CLI output file
37-
29. [**veracode-mapper**] - Veracode Scan Results XML file
38-
30. [**xccdf-results-mapper**] - SCAP client XCCDF-Results XML report
39-
31. [**zap-mapper**] - OWASP ZAP results JSON
32+
24. [**semgrep-mapper**] - Semgrep static analysis results JSON file
33+
25. [**snyk-mapper**] - Snyk results JSON file
34+
26. [**sonarqube-mapper**] - SonarQube vulnerabilities for the specified project name and optional branch or pull/merge request ID name from an API
35+
27. [**splunk-mapper**] - Splunk instance
36+
28. [**trufflehog-mapper**] - Trufflehog results json file
37+
29. [**twistlock-mapper**] - Twistlock CLI output file
38+
30. [**veracode-mapper**] - Veracode Scan Results XML file
39+
31. [**xccdf-results-mapper**] - SCAP client XCCDF-Results XML report
40+
32. [**zap-mapper**] - OWASP ZAP results JSON
4041

4142
### NOTICE
4243

libs/hdf-converters/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export * from './src/nikto-mapper';
3737
export * from './src/prisma-mapper';
3838
export * from './src/sarif-mapper';
3939
export * from './src/scoutsuite-mapper';
40+
export * from './src/semgrep-mapper';
4041
export * from './src/snyk-mapper';
4142
export * from './src/sonarqube-mapper';
4243
export * from './src/splunk-mapper';
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"version": "1.174.0",
3+
"results": [],
4+
"errors": [],
5+
"paths": {
6+
"scanned": [
7+
"clean/constants.py"
8+
]
9+
},
10+
"time": {
11+
"rules": [],
12+
"rules_parse_time": 0.22119784355163574,
13+
"profiling_times": {
14+
"config_time": 0.5635168552398682,
15+
"core_time": 0.4694981575012207,
16+
"ignores_time": 0.0006928443908691406,
17+
"total_time": 1.0411698818206787
18+
},
19+
"parsing_time": {
20+
"total_time": 0.0,
21+
"per_file_time": {
22+
"mean": 0.0,
23+
"std_dev": 0.0
24+
},
25+
"very_slow_stats": {
26+
"time_ratio": 0.0,
27+
"count_ratio": 0.0
28+
},
29+
"very_slow_files": []
30+
},
31+
"scanning_time": {
32+
"total_time": 0.008240938186645508,
33+
"per_file_time": {
34+
"mean": 0.0027469793955485025,
35+
"std_dev": 1.234643443442312e-05
36+
},
37+
"very_slow_stats": {
38+
"time_ratio": 0.0,
39+
"count_ratio": 0.0
40+
},
41+
"very_slow_files": []
42+
},
43+
"matching_time": {
44+
"total_time": 0.0,
45+
"per_file_and_rule_time": {
46+
"mean": 0.0,
47+
"std_dev": 0.0
48+
},
49+
"very_slow_stats": {
50+
"time_ratio": 0.0,
51+
"count_ratio": 0.0
52+
},
53+
"very_slow_rules_on_files": []
54+
},
55+
"tainting_time": {
56+
"total_time": 0.0,
57+
"per_def_and_rule_time": {
58+
"mean": 0.0,
59+
"std_dev": 0.0
60+
},
61+
"very_slow_stats": {
62+
"time_ratio": 0.0,
63+
"count_ratio": 0.0
64+
},
65+
"very_slow_rules_on_defs": []
66+
},
67+
"fixpoint_timeouts": [],
68+
"prefiltering": {
69+
"project_level_time": 0.0,
70+
"file_level_time": 0.0,
71+
"rules_with_project_prefilters_ratio": 0.0,
72+
"rules_with_file_prefilters_ratio": 0.9896551724137931,
73+
"rules_selected_ratio": 0.010344827586206896,
74+
"rules_matched_ratio": 0.010344827586206896
75+
},
76+
"targets": [],
77+
"total_bytes": 0,
78+
"max_memory_bytes": 754748608
79+
},
80+
"engine_requested": "OSS",
81+
"skipped_rules": [],
82+
"profiling_results": []
83+
}

0 commit comments

Comments
 (0)