diff --git a/writehat/components/FindingsStatusList.py b/writehat/components/FindingsStatusList.py
new file mode 100644
index 0000000..3902d60
--- /dev/null
+++ b/writehat/components/FindingsStatusList.py
@@ -0,0 +1,11 @@
+import logging
+from .base import *
+
+log = logging.getLogger(__name__)
+
+class Component(BaseComponent):
+
+ default_name = 'Summary of Findings Status'
+ htmlTemplate = 'componentTemplates/FindingsStatusList.html'
+ iconType = 'fas fa-th-list'
+ iconColor = 'var(--orange)'
\ No newline at end of file
diff --git a/writehat/lib/finding.py b/writehat/lib/finding.py
index 719ff68..74c0e5a 100644
--- a/writehat/lib/finding.py
+++ b/writehat/lib/finding.py
@@ -27,6 +27,17 @@ class BaseDatabaseFinding(WriteHatBaseModel):
background = MarkdownField(max_length=30000, null=True, blank=True)
remediation = MarkdownField(max_length=30000, null=True, blank=True)
references = MarkdownField(max_length=30000, null=True, blank=True)
+ retest = MarkdownField(max_length=30000, null=True, blank=True)
+ # status choices
+ status_choices = (
+ ("Open", "Open"),
+ ("Partially Fixed", "Partially Fixed"),
+ ("Risk Accepted", "Risk Accepted"),
+ ("Fixed", "Fixed"),
+ ("Not Fixed", "Not Fixed"),
+ ("Closed", "Closed"),
+)
+ status = models.CharField(max_length=30, choices=status_choices, default="Open")
# Overridden by child class
scoringType = models.CharField(default='None', max_length=50)
diff --git a/writehat/lib/findingForm.py b/writehat/lib/findingForm.py
index cc46c13..eff7aa8 100644
--- a/writehat/lib/findingForm.py
+++ b/writehat/lib/findingForm.py
@@ -29,6 +29,12 @@ class FindingForm(forms.Form):
max_length=30000,
required=False)
+ retest = forms.CharField(
+ label='Retest',
+ widget=forms.Textarea(),
+ max_length=30000,
+ required=False)
+
categoryID = forms.UUIDField(
label='Category',
widget=CategoryBootstrapSelectEngagements(
@@ -36,6 +42,19 @@ class FindingForm(forms.Form):
),
required=True)
+ #vulnerability status
+ statusChoices = (
+ ("Open", "Open"),
+ ("Partially Fixed", "Partially Fixed"),
+ ("Risk Accepted", "Risk Accepted"),
+ ("Fixed", "Fixed"),
+ ("Not Fixed", "Not Fixed"),
+ ("Closed", "Closed")
+ )
+ status = forms.ChoiceField(choices=statusChoices,
+ label='Status',
+ required=True)
+
@property
def className(self):
@@ -420,7 +439,7 @@ def __init__(self, *args, **kwargs):
class CVSSEngagementFindingForm(EngagementFindingForm,CVSSForm):
findingGroup = forms.UUIDField(label='Finding Group',required=True)
- field_order = ['name','findingGroup','categoryID','description','affectedResources','background','proofOfConcept','toolsUsed','remediation','references','cvssAV','cvssAC','cvssPR','cvssUI','cvssS','cvssC','cvssI','cvssA','cvssE','cvssRL','cvssRC','cvssCR','cvssIR','cvssAR','cvssMAV','cvssMAC','cvssMPR','cvssMUI','cvssMS','cvssMC','cvssMI','cvssMA',]
+ field_order = ['name','status','findingGroup','categoryID','description','affectedResources','background','proofOfConcept','retest','toolsUsed','remediation','references','cvssAV','cvssAC','cvssPR','cvssUI','cvssS','cvssC','cvssI','cvssA','cvssE','cvssRL','cvssRC','cvssCR','cvssIR','cvssAR','cvssMAV','cvssMAC','cvssMPR','cvssMUI','cvssMS','cvssMC','cvssMI','cvssMA',]
class DREADEngagementFindingForm(EngagementFindingForm,DREADForm):
@@ -452,12 +471,14 @@ class DREADEngagementFindingForm(EngagementFindingForm,DREADForm):
field_order = [
'name',
+ 'status',
'findingGroup',
'categoryID',
'description',
'affectedResources',
'dreadImpact',
'background',
+ 'retest',
'remediation',
'references',
'dreadDamage',
@@ -476,7 +497,7 @@ class DREADEngagementFindingForm(EngagementFindingForm,DREADForm):
class ProactiveEngagementFindingForm(EngagementFindingForm,ProactiveForm):
findingGroup = forms.UUIDField(label='Finding Group',required=True)
- field_order = ['name','findingGroup','categoryID','description','affectedResources','background','references']
+ field_order = ['name','status','findingGroup','categoryID','description','affectedResources','background','retest','references']
class CVSSDatabaseFindingForm(CVSSForm):
diff --git a/writehat/static/css/component/FindingsList.css b/writehat/static/css/component/FindingsList.css
index 270c56b..0356f19 100644
--- a/writehat/static/css/component/FindingsList.css
+++ b/writehat/static/css/component/FindingsList.css
@@ -112,6 +112,16 @@
background-color: var(--stripe-background-color);
}
+div.finding div.finding-content > div.status::before { content: "Status" !important; }
+div.finding div.finding-content > div.category::before { content: "Category" !important; }
+div.finding div.finding-content > div.affected-resources::before { content: "Affected Resources" !important; }
+div.finding div.finding-content > div.description::before { content: "Description" !important; }
+div.finding div.finding-content > div.background::before { content: "Background" !important; }
+div.finding div.finding-content > div.retest::before { content: "Retest" !important; }
+div.finding div.finding-content > div.remediation::before { content: "Remediation" !important; }
+div.finding div.finding-content > div.references::before { content: "References" !important; }
+
+/* CVSS SPECIFIC */
.finding .finding-content:last-child{
height: 100%;
}
diff --git a/writehat/static/css/component/FindingsStatusList.css b/writehat/static/css/component/FindingsStatusList.css
new file mode 100644
index 0000000..a636e1a
--- /dev/null
+++ b/writehat/static/css/component/FindingsStatusList.css
@@ -0,0 +1,89 @@
+div.finding-group-name {
+ padding: .5em;
+ margin: .5em;
+ font-weight: bold;
+ font-size: 1.1em;
+ width: 100%;
+ text-align: center;
+ }
+
+ p.findings-status-summary-entry {
+ padding: .5rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ margin: 0 10rem 2px calc(2rem + 4px);
+ position: relative;
+ background-color: #BEDDBA;
+ }
+
+ p.findings-status-summary-entry::before {
+ content: '';
+ padding: 1rem;
+ position: absolute;
+ background-color: #7BB274;
+ display: inline-block;
+ left: calc(-2rem - 2px);
+ bottom: 0;
+ top: 0;
+ }
+
+ p.findings-status-summary-entry::after {
+ content: attr(finding-status);
+ padding: .5rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ position: absolute;
+ background-color: #BEDDBA;
+ display: inline-block;
+ left: calc(36.8rem + 2px);
+ bottom: 0;
+ top: 0;
+ color: black;
+ font-weight: bold;
+ font-size: 16px;
+ overflow: hidden;
+ white-space: nowrap;
+ width: 8rem;
+ text-align: center;
+}
+
+ p.findings-status-summary-entry a {
+ text-decoration: none;
+ color: black;
+ font-weight: bold;
+ font-size: 16px;
+ }
+
+ p.findings-status-summary-title-entry {
+ color: black;
+ padding: .5rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ margin: 0 10rem 2px calc(2rem + 4px);
+ position: relative;
+ text-decoration: none;
+ color: black;
+ font-weight: bold;
+ font-size: 16px;
+}
+
+ p.findings-status-summary-title-entry::after {
+ content: 'Status';
+ padding: .5rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ position: absolute;
+ background-color: #ffffff;
+ display: inline-block;
+ left: calc(36.8rem + 2px);
+ bottom: 0;
+ top: 0;
+ color: black;
+ font-weight: bold;
+ font-size: 16px;
+ overflow: hidden;
+ white-space: nowrap;
+ width: 8rem;
+ text-align: center;
+}
+
diff --git a/writehat/templates/componentTemplates/CVSSFinding.html b/writehat/templates/componentTemplates/CVSSFinding.html
index 8126588..0439de7 100644
--- a/writehat/templates/componentTemplates/CVSSFinding.html
+++ b/writehat/templates/componentTemplates/CVSSFinding.html
@@ -13,6 +13,24 @@
{{ finding.severity }}
+
+ {% endif %}
+ {% if showStatus %}
+
+ Finding +
+ {% for finding in fgroup %} + {% if not report.finding_uuids or finding.id in report.finding_uuids %} + + {% endif %} + {% endfor %} + + {% endif %} + {% endfor %} +