Skip to content

Commit 82fbe14

Browse files
committed
fix: address gap analysis findings for IriusRisk parser
- Update test CSVs from 12 to 14 columns (add MITRE reference, STRIDE-LM) - Parse MITRE reference: CWE-NNN extracts to cwe field, other values to references - Include STRIDE-LM in description when populated - Add Critical to severity mapping - Change static_finding to False per connector spec - Update documentation to reflect all changes - Add tests for CWE extraction, references, STRIDE-LM, and Critical severity Authored by T. Walker - DefectDojo
1 parent c5143eb commit 82fbe14

6 files changed

Lines changed: 104 additions & 41 deletions

File tree

docs/content/supported_tools/parsers/file/iriusrisk.md

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ Sample IriusRisk scans can be found in the [sample scan data folder](https://git
4040

4141
### Total Fields in CSV
4242

43-
- Total data fields: 12
44-
- Total data fields parsed: 12
43+
- Total data fields: 14
44+
- Total data fields parsed: 14
4545
- Total data fields NOT parsed: 0
4646

4747
### CSV Format Field Mapping Details
@@ -51,22 +51,25 @@ Sample IriusRisk scans can be found in the [sample scan data folder](https://git
5151

5252
| Source Field | DefectDojo Field | Parser Line # | Notes |
5353
| ------------------------ | -------------------- | ------------- | --------------------------------------------------------------------- |
54-
| Threat | title | 47 | Truncated to 150 characters with "..." suffix if longer |
55-
| Current Risk | severity | 49 | Mapped from IriusRisk risk levels to DefectDojo severity levels |
56-
| Component | component_name | 79 | The affected asset or component from the threat model |
57-
| Threat | description | 53 | Full threat text included as first line of structured description |
58-
| Component | description | 54 | Included in structured description block |
59-
| Use case | description | 55 | Threat category included in structured description |
60-
| Source | description | 56 | Origin of the threat included in structured description |
61-
| Inherent Risk | description | 57 | Pre-control risk level included in structured description |
62-
| Current Risk | description | 58 | Current risk level included in structured description |
63-
| Projected Risk | description | 59 | Post-mitigation risk level included in structured description |
64-
| Countermeasure progress | description | 60 | Percentage complete included in structured description |
65-
| Weakness tests | description | 61 | Test status included in structured description |
66-
| Countermeasure tests | description | 62 | Test status included in structured description |
67-
| Owner | description | 64-65 | Conditionally appended to description only when present |
68-
| Risk Response | mitigation | 78 | Mitigation status percentages from IriusRisk |
69-
| Component + Threat + Risk Response | unique_id_from_tool | 69-71 | SHA-256 hash used for deduplication across reimports |
54+
| Threat | title | 51 | Truncated to 150 characters with "..." suffix if longer |
55+
| Current Risk | severity | 53 | Mapped from IriusRisk risk levels to DefectDojo severity levels |
56+
| Component | component_name | 95 | The affected asset or component from the threat model |
57+
| Threat | description | 57 | Full threat text included as first line of structured description |
58+
| Component | description | 58 | Included in structured description block |
59+
| Use case | description | 59 | Threat category included in structured description |
60+
| Source | description | 60 | Origin of the threat included in structured description |
61+
| Inherent Risk | description | 61 | Pre-control risk level included in structured description |
62+
| Current Risk | description | 62 | Current risk level included in structured description |
63+
| Projected Risk | description | 63 | Post-mitigation risk level included in structured description |
64+
| Countermeasure progress | description | 64 | Percentage complete included in structured description |
65+
| Weakness tests | description | 65 | Test status included in structured description |
66+
| Countermeasure tests | description | 66 | Test status included in structured description |
67+
| Owner | description | 68-69 | Conditionally appended to description only when present |
68+
| STRIDE-LM | description | 70-71 | Conditionally appended to description only when present |
69+
| Risk Response | mitigation | 94 | Mitigation status percentages from IriusRisk |
70+
| MITRE reference | cwe | 82-85 | When value matches CWE-NNN pattern, integer is extracted to cwe field |
71+
| MITRE reference | references | 86-87 | When value does not match CWE pattern, stored as references |
72+
| Component + Threat + Risk Response | unique_id_from_tool | 74-77 | SHA-256 hash used for deduplication across reimports |
7073

7174
</details>
7275

@@ -77,33 +80,34 @@ Sample IriusRisk scans can be found in the [sample scan data folder](https://git
7780

7881
| Finding Field | Default Value | Parser Line # | Notes |
7982
| ---------------- | -------------------------------- | ------------- | ----------------------------------------------------------- |
80-
| static_finding | True | 81 | Threat model data is static analysis |
81-
| dynamic_finding | False | 82 | Not from live scanning |
82-
| active | True (False when "Very low") | 80 | Set to False when Current Risk is "Very low" (fully mitigated) |
83-
| unique_id_from_tool | SHA-256 hash | 83 | Hash of Component, Threat, and Risk Response |
83+
| static_finding | False | 97 | Threat model data is neither static nor dynamic analysis |
84+
| dynamic_finding | False | 98 | Threat model data is neither static nor dynamic analysis |
85+
| active | True (False when "Very low") | 96 | Set to False when Current Risk is "Very low" (fully mitigated) |
86+
| unique_id_from_tool | SHA-256 hash | 99 | Hash of Component, Threat, and Risk Response |
8487

8588
</details>
8689

8790
## Special Processing Notes
8891

8992
### Status Conversion
9093

91-
IriusRisk uses a four-level risk scale that is mapped to DefectDojo severity levels (lines 7-12):
94+
IriusRisk uses a five-level risk scale that is mapped to DefectDojo severity levels (lines 8-14):
9295

96+
- `Critical` → Critical
9397
- `High` → High
9498
- `Medium` → Medium
9599
- `Low` → Low
96100
- `Very low` → Info
97101

98-
Any unrecognized risk value defaults to Info (line 49). The mapping uses the "Current Risk" column, which reflects the risk level accounting for existing controls and represents the most accurate current exposure.
102+
Any unrecognized risk value defaults to Info (line 53). The mapping uses the "Current Risk" column, which reflects the risk level accounting for existing controls and represents the most accurate current exposure.
99103

100104
### Title Format
101105

102-
Finding titles are derived from the "Threat" column (line 47). Threat descriptions longer than 150 characters are truncated to 147 characters with a "..." suffix appended. Shorter threat texts are used as-is without modification.
106+
Finding titles are derived from the "Threat" column (line 51). Threat descriptions longer than 150 characters are truncated to 147 characters with a "..." suffix appended. Shorter threat texts are used as-is without modification.
103107

104108
### Description Construction
105109

106-
The parser constructs a structured markdown description containing all 12 CSV fields (lines 52-66):
110+
The parser constructs a structured markdown description containing all relevant CSV fields (lines 56-72):
107111

108112
1. Full threat text (untruncated, regardless of title truncation)
109113
2. Component name
@@ -116,20 +120,29 @@ The parser constructs a structured markdown description containing all 12 CSV fi
116120
9. Weakness Tests (test status)
117121
10. Countermeasure Tests (test status)
118122
11. Owner (conditionally included only when the field contains a value)
123+
12. STRIDE-LM (conditionally included only when the field contains a value)
119124

120125
Each field is formatted as a bold markdown label followed by the value, with fields separated by newlines.
121126

127+
### MITRE Reference / CWE Extraction
128+
129+
The parser reads the "MITRE reference" column (lines 79-87) and applies conditional mapping:
130+
131+
- If the value matches the pattern `CWE-NNN` (e.g., "CWE-284"), the integer portion is extracted and set on the finding's `cwe` field.
132+
- If the value is present but does not match the CWE pattern (e.g., "T1059" for a MITRE ATT&CK technique), the full value is stored in the finding's `references` field.
133+
- If the column is empty, neither field is set.
134+
122135
### Mitigation Construction
123136

124-
The mitigation field is populated directly from the "Risk Response" column (line 78), which contains the IriusRisk mitigation status in the format: "Planned mitigation: X%. Mitigated: Y%. Unmitigated: Z%." This preserves the original IriusRisk mitigation tracking percentages.
137+
The mitigation field is populated directly from the "Risk Response" column (line 94), which contains the IriusRisk mitigation status in the format: "Planned mitigation: X%. Mitigated: Y%. Unmitigated: Z%." This preserves the original IriusRisk mitigation tracking percentages.
125138

126139
### Active/Inactive Logic
127140

128-
Findings are set to active by default (line 80). When the "Current Risk" value is "Very low", the finding is set to inactive, as this indicates the threat has been fully mitigated through implemented countermeasures.
141+
Findings are set to active by default (line 96). When the "Current Risk" value is "Very low", the finding is set to inactive, as this indicates the threat has been fully mitigated through implemented countermeasures.
129142

130143
### Deduplication
131144

132-
The parser generates a `unique_id_from_tool` by computing a SHA-256 hash of the Component, Threat, and Risk Response fields concatenated with pipe delimiters (lines 69-71). This ensures that each distinct combination of component, threat, and mitigation state produces a unique identifier. On reimport, findings with matching unique IDs are recognized as the same finding rather than being duplicated.
145+
The parser generates a `unique_id_from_tool` by computing a SHA-256 hash of the Component, Threat, and Risk Response fields concatenated with pipe delimiters (lines 74-77). This ensures that each distinct combination of component, threat, and mitigation state produces a unique identifier. On reimport, findings with matching unique IDs are recognized as the same finding rather than being duplicated.
133146

134147
### Duplicate Rows in Source Data
135148

dojo/tools/iriusrisk/parser.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import csv
22
import hashlib
33
import io
4+
import re
45

56
from dojo.models import Finding
67

@@ -9,6 +10,7 @@
910
"Low": "Low",
1011
"Medium": "Medium",
1112
"High": "High",
13+
"Critical": "Critical",
1214
}
1315

1416

@@ -42,6 +44,8 @@ def get_findings(self, filename, test):
4244
countermeasure_tests = (row.get("Countermeasure tests") or "").strip()
4345
projected_risk = (row.get("Projected Risk") or "").strip()
4446
owner = (row.get("Owner") or "").strip()
47+
mitre_reference = (row.get("MITRE reference") or "").strip()
48+
stride_lm = (row.get("STRIDE-LM") or "").strip()
4549

4650
# Title: truncate to 150 chars with ellipsis if needed
4751
title = threat[:147] + "..." if len(threat) > 150 else threat
@@ -63,13 +67,25 @@ def get_findings(self, filename, test):
6367
]
6468
if owner:
6569
description_parts.append(f"**Owner:** {owner}")
70+
if stride_lm:
71+
description_parts.append(f"**STRIDE-LM:** {stride_lm}")
6672
description = "\n".join(description_parts)
6773

6874
# Unique ID for deduplication across reimports
6975
unique_id = hashlib.sha256(
7076
f"{component}|{threat}|{risk_response}".encode(),
7177
).hexdigest()
7278

79+
# Extract CWE from MITRE reference if present
80+
cwe = None
81+
references = ""
82+
if mitre_reference:
83+
cwe_match = re.match(r"CWE-(\d+)", mitre_reference)
84+
if cwe_match:
85+
cwe = int(cwe_match.group(1))
86+
else:
87+
references = mitre_reference
88+
7389
finding = Finding(
7490
test=test,
7591
title=title,
@@ -78,9 +94,13 @@ def get_findings(self, filename, test):
7894
mitigation=risk_response,
7995
component_name=component,
8096
active=current_risk != "Very low",
81-
static_finding=True,
97+
static_finding=False,
8298
dynamic_finding=False,
8399
unique_id_from_tool=unique_id,
84100
)
101+
if cwe:
102+
finding.cwe = cwe
103+
if references:
104+
finding.references = references
85105
findings.append(finding)
86106
return findings
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
"Component","Use case","Source","Threat","Risk Response","Inherent Risk","Current Risk","Countermeasure progress","Weakness tests","Countermeasure tests","Projected Risk","Owner"
2-
"Router","Elevation of Privilege","Created by Rules Engine","Accessing functionality not properly constrained by ACLs","Planned mitigation: 0%. Mitigated: 0%. Unmitigated: 100%.","High","High","0%","Not tested","Not tested","High",
3-
"API UX Authorization Management","Read or Post data","Created by Rules Engine","An adversary attempts to exploit an application by injecting additional, malicious content during its processing","Planned mitigation: 100%. Mitigated: 0%. Unmitigated: 0%.","Medium","Medium","0%","Not tested","Not tested","Very low",
4-
"API BS Connection Interface Reporting","Read or Post data","Created by Rules Engine","An attacker crafts malicious web links and distributes them hoping to induce users to click on the link","Planned mitigation: 34%. Mitigated: 66%. Unmitigated: 0%.","High","Low","66%","Not tested","Not tested","Very low",
5-
"app-srec-audit-events","Networking","Created by Rules Engine","Access to network traffic from other containers creates the potential for various types of attacks such as denial of service or spoofing attack","Planned mitigation: 0%. Mitigated: 100%. Unmitigated: 0%.","High","Very low","100%","Not tested","Not tested","Very low",
6-
"API BS Service Provider","General","Created by Rules Engine","An attacker injects, manipulates or forges malicious log entries in the log file, allowing her to mislead a log audit, cover traces of attack, or perform other malicious actions","Planned mitigation: 100%. Mitigated: 0%. Unmitigated: 0%.","Medium","Medium","0%","Not tested","Not tested","Very low","John Smith"
1+
"Component","Use case","Source","Threat","Risk Response","Inherent Risk","Current Risk","Countermeasure progress","Weakness tests","Countermeasure tests","Projected Risk","Owner","MITRE reference","STRIDE-LM"
2+
"Router","Elevation of Privilege","Created by Rules Engine","Accessing functionality not properly constrained by ACLs","Planned mitigation: 0%. Mitigated: 0%. Unmitigated: 100%.","High","High","0%","Not tested","Not tested","High",,"CWE-284","Elevation of Privilege"
3+
"API UX Authorization Management","Read or Post data","Created by Rules Engine","An adversary attempts to exploit an application by injecting additional, malicious content during its processing","Planned mitigation: 100%. Mitigated: 0%. Unmitigated: 0%.","Medium","Medium","0%","Not tested","Not tested","Very low",,"T1059",
4+
"API BS Connection Interface Reporting","Read or Post data","Created by Rules Engine","An attacker crafts malicious web links and distributes them hoping to induce users to click on the link","Planned mitigation: 34%. Mitigated: 66%. Unmitigated: 0%.","High","Low","66%","Not tested","Not tested","Very low",,,
5+
"app-srec-audit-events","Networking","Created by Rules Engine","Access to network traffic from other containers creates the potential for various types of attacks such as denial of service or spoofing attack","Planned mitigation: 0%. Mitigated: 100%. Unmitigated: 0%.","High","Very low","100%","Not tested","Not tested","Very low",,,
6+
"API BS Service Provider","General","Created by Rules Engine","An attacker injects, manipulates or forges malicious log entries in the log file, allowing her to mislead a log audit, cover traces of attack, or perform other malicious actions","Planned mitigation: 100%. Mitigated: 0%. Unmitigated: 0%.","Medium","Medium","0%","Not tested","Not tested","Very low","John Smith",,
7+
"Database Server","Data Storage","Created by Rules Engine","An attacker targets the database server to exfiltrate sensitive records","Planned mitigation: 0%. Mitigated: 0%. Unmitigated: 100%.","Critical","Critical","0%","Not tested","Not tested","Critical",,,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"Component","Use case","Source","Threat","Risk Response","Inherent Risk","Current Risk","Countermeasure progress","Weakness tests","Countermeasure tests","Projected Risk","Owner"
1+
"Component","Use case","Source","Threat","Risk Response","Inherent Risk","Current Risk","Countermeasure progress","Weakness tests","Countermeasure tests","Projected Risk","Owner","MITRE reference","STRIDE-LM"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
"Component","Use case","Source","Threat","Risk Response","Inherent Risk","Current Risk","Countermeasure progress","Weakness tests","Countermeasure tests","Projected Risk","Owner"
2-
"Router","Elevation of Privilege","Created by Rules Engine","Accessing functionality not properly constrained by ACLs","Planned mitigation: 0%. Mitigated: 0%. Unmitigated: 100%.","High","High","0%","Not tested","Not tested","High",
1+
"Component","Use case","Source","Threat","Risk Response","Inherent Risk","Current Risk","Countermeasure progress","Weakness tests","Countermeasure tests","Projected Risk","Owner","MITRE reference","STRIDE-LM"
2+
"Router","Elevation of Privilege","Created by Rules Engine","Accessing functionality not properly constrained by ACLs","Planned mitigation: 0%. Mitigated: 0%. Unmitigated: 100%.","High","High","0%","Not tested","Not tested","High",,,

0 commit comments

Comments
 (0)