Skip to content

Commit

Permalink
Merge pull request DefectDojo#10356 from DefectDojo/master-into-dev/2…
Browse files Browse the repository at this point in the history
….35.1-2.36.0-dev

Release: Merge back 2.35.1 into dev from: master-into-dev/2.35.1-2.36.0-dev
  • Loading branch information
Maffooch authored Jun 6, 2024
2 parents 5714e20 + 07c061f commit 6b9fd8c
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 20 deletions.
4 changes: 2 additions & 2 deletions dojo/api_v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3013,8 +3013,8 @@ def validate(self, data):

class UserProfileSerializer(serializers.Serializer):
user = UserSerializer(many=False)
user_contact_info = UserContactInfoSerializer(many=False)
global_role = GlobalRoleSerializer(many=False)
user_contact_info = UserContactInfoSerializer(many=False, required=False)
global_role = GlobalRoleSerializer(many=False, required=False)
dojo_group_member = DojoGroupMemberSerializer(many=True)
product_type_member = ProductTypeMemberSerializer(many=True)
product_member = ProductMemberSerializer(many=True)
Expand Down
11 changes: 7 additions & 4 deletions dojo/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,8 @@ def set_date_fields(self, *args: list, **kwargs: dict):


class FindingFilterWithoutObjectLookups(FindingFilterHelper, FindingTagStringFilter):
test__engagement__product__prod_type = NumberFilter(widget=HiddenInput())
test__engagement__product = NumberFilter(widget=HiddenInput())
reporter = CharFilter(
field_name="reporter__username",
lookup_expr="iexact",
Expand All @@ -1673,13 +1675,13 @@ class FindingFilterWithoutObjectLookups(FindingFilterHelper, FindingTagStringFil
lookup_expr="icontains",
label="Reporter Username Contains",
help_text="Search for Reporter names that contain a given pattern")
reviewer = CharFilter(
field_name="reviewer__username",
reviewers = CharFilter(
field_name="reviewers__username",
lookup_expr="iexact",
label="Reviewer Username",
help_text="Search for Reviewer names that are an exact match")
reviewer_contains = CharFilter(
field_name="reviewer__username",
reviewers_contains = CharFilter(
field_name="reviewers__username",
lookup_expr="icontains",
label="Reviewer Username Contains",
help_text="Search for Reviewer usernames that contain a given pattern")
Expand Down Expand Up @@ -2471,6 +2473,7 @@ class Meta:


class EndpointFilterWithoutObjectLookups(EndpointFilterHelper):
product = NumberFilter(widget=HiddenInput())
product__name = CharFilter(
field_name="product__name",
lookup_expr="iexact",
Expand Down
2 changes: 1 addition & 1 deletion dojo/importers/default_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def process_findings(
group_name,
findings,
self.group_by,
self.create_finding_groups_for_all_findings,
create_finding_groups_for_all_findings=self.create_finding_groups_for_all_findings,
**kwargs
)
if self.push_to_jira:
Expand Down
2 changes: 2 additions & 0 deletions dojo/importers/default_reimporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,8 @@ def process_groups_for_all_findings(
finding_helper.add_findings_to_auto_group(
group_name,
findings,
self.group_by,
create_finding_groups_for_all_findings=self.create_finding_groups_for_all_findings,
**kwargs
)
if self.push_to_jira:
Expand Down
8 changes: 4 additions & 4 deletions dojo/importers/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
Endpoint,
Engagement,
Finding,
Product_API_Scan_Configuration,
Test,
Test_Import,
Tool_Configuration,
)
from dojo.utils import get_current_user, is_finding_groups_enabled

Expand Down Expand Up @@ -45,7 +45,7 @@ def load_base_options(
**kwargs: dict,
):
self.active: bool = self.validate_active(*args, **kwargs)
self.api_scan_configuration: Tool_Configuration | None = self.validate_api_scan_configuration(*args, **kwargs)
self.api_scan_configuration: Product_API_Scan_Configuration | None = self.validate_api_scan_configuration(*args, **kwargs)
self.apply_tags_to_endpoints: bool = self.validate_apply_tags_to_endpoints(*args, **kwargs)
self.apply_tags_to_findings: bool = self.validate_apply_tags_to_findings(*args, **kwargs)
self.branch_tag: str = self.validate_branch_tag(*args, **kwargs)
Expand Down Expand Up @@ -227,10 +227,10 @@ def validate_api_scan_configuration(
self,
*args: list,
**kwargs: dict,
) -> Tool_Configuration | None:
) -> Product_API_Scan_Configuration | None:
return self.validate(
"api_scan_configuration",
expected_types=[Tool_Configuration],
expected_types=[Product_API_Scan_Configuration],
required=False,
default=None,
**kwargs,
Expand Down
6 changes: 3 additions & 3 deletions dojo/tools/netsparker/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ def get_findings(self, filename, test):
url = item["Url"]
impact = html2text.html2text(item.get("Impact", ""))
dupe_key = title
request = item["HttpRequest"]["Content"]
response = item["HttpResponse"]["Content"]
request = item["HttpRequest"].get("Content", None)
response = item["HttpResponse"].get("Content", None)

finding = Finding(
title=title,
Expand Down Expand Up @@ -89,7 +89,7 @@ def get_findings(self, filename, test):
)
if len(cvss_objects) > 0:
finding.cvssv3 = cvss_objects[0].clean_vector()
finding.unsaved_req_resp = [{"req": request, "resp": response}]
finding.unsaved_req_resp = [{"req": str(request), "resp": str(response)}]
finding.unsaved_endpoints = [Endpoint.from_uri(url)]

if dupe_key in dupes:
Expand Down
10 changes: 5 additions & 5 deletions helm/defectdojo/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ dependencies:
version: 9.19.1
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 15.5.1
version: 15.5.4
- name: postgresql-ha
repository: https://charts.bitnami.com/bitnami
version: 9.4.11
- name: rabbitmq
repository: https://charts.bitnami.com/bitnami
version: 14.4.0
version: 14.4.1
- name: redis
repository: https://charts.bitnami.com/bitnami
version: 19.5.0
digest: sha256:a10fdb3b920ee07af57ab5bd51a3644419d75a8092f8192087b6c65d0b94b102
generated: "2024-06-06T09:34:00.777315379Z"
version: 19.5.2
digest: sha256:bbb03050d96cdc317d8088bb62b53a0b892746fd1e5763f7c374da31d3d30895
generated: "2024-06-06T21:33:03.331847962Z"
2 changes: 1 addition & 1 deletion helm/defectdojo/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
appVersion: "2.36.0-dev"
description: A Helm chart for Kubernetes to install DefectDojo
name: defectdojo
version: 1.6.133-dev
version: 1.6.134-dev
icon: https://www.defectdojo.org/img/favicon.ico
maintainers:
- name: madchap
Expand Down
173 changes: 173 additions & 0 deletions unittests/scans/netsparker/issue_10311.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
{
"Generated": "03/02/2019 15:50:29 (UTC-06:00)",
"Target": {
"ScanId": "fg49hk5",
"Url": "https://www.sampleweb.org/",
"Initiated": "03/02/2019 15:48:23 (UTC-06:00)",
"Duration": "00:01:20.4322725"
},
"Vulnerabilities": [
{
"Url": "https://www.sampleweb.org/",
"Type": "CookieNotMarkedAsSecure",
"Name": "Cookie Not Marked as Secure",
"Severity": "High",
"Certainty": 100,
"Confirmed": true,
"Classification": {
"Owasp": "A6",
"Owasp2017": "A3",
"Wasc": "15",
"Cwe": "614",
"Capec": "102",
"Pci31": "6.5.10",
"Pci32": "6.5.10",
"Hipaa": null
},
"HttpRequest": {
"Method": "GET",
"Content": "GET / HTTP/1.1\r\nHost: www.sampleweb.org\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-us,en;q=0.5\r\nCache-Control: no-cache\r\nUser-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)\r\nX-Scanner: Netsparker\r\n\r\n",
"Parameters": [ ]
},
"HttpResponse": {
"StatusCode": 200,
"Duration": 644.6389,
"Content": "HTTP/1.1 200 OK\r\nX-Cache: MISS\r\nX-Timer: S1551563304.277046,VS0,VE20\r\nAge: 0\r\nCache-Control: max-age=600\r\nETag: W/\"5b8fd2e9-6807\"\r\nAccess-Control-Allow-Origin: *\r\nX-Fastly-Request-ID: 0345654a04250c6d1c420d386643c1f6dc7c3c24\r\nX-Served-By: cache-chi21166-CHI\r\nConnection: keep-alive\r\nExpires: Sat, 02 Mar 2019 21:58:24 GMT\r\nAccept-Ranges: bytes\r\nX-Cache-Hits: 0\r\nContent-Length: 5954\r\nX-GitHub-Request-Id: 0820:594C:6A9400:84F805:5C7AFA26\r\nVary: Accept-Encoding\r\nVia: 1.1 varnish\r\nLast-Modified: Wed, 05 Sep 2018 12:58:17 GMT\r\nContent-Type: text/html; charset=utf-8\r\nServer: GitHub.com\r\nDate: Sat, 02 Mar 2019 21:48:24 GMT\r\nContent-Encoding: \r\n\r\n"
},
"ExtraInformation": [
{
"Name": "Identified Cookie(s)",
"Value": "cookieconsent_status"
},
{
"Name": "Cookie Source",
"Value": "JavaScript"
}
],
"KnownVulnerabilities": [ ],
"Description": "<p>Netsparker identified a cookie not marked as secure, and transmitted over HTTPS.</p><p>This means the cookie could potentially be stolen by an attacker who can successfully intercept and decrypt the traffic, or following a successful man-in-the-middle attack.</p>",
"Impact": "<div>This cookie will be transmitted over a HTTP connection, therefore if this cookie is important (<em>such as a session cookie</em>), an attacker might intercept it and hijack a victim's session. If the attacker can carry out a man-in-the-middle attack, he/she can force the victim to make an HTTP request to steal the cookie.</div>",
"RemedialActions": "<div><ol><li>See the remedy for solution.</li><li>Mark all cookies used within the application as secure. <em>(If the cookie is not related to authentication or does not carry any personal information, you do not have to mark it as secure.)</em></li></ol></div>",
"ExploitationSkills": "<div>To exploit this issue, the attacker needs to be able to intercept traffic. This generally requires local access to the web server or to the victim's network. Attackers need to be understand layer 2, have physical access to systems either as waypoints for the traffic, or have locally gained access to to a system between the victim and the web server.</div>",
"RemedialProcedure": "<div>Mark all cookies used within the application as secure.</div>",
"RemedyReferences": "",
"ExternalReferences": "<div><ul><li><a href='https://msdn.microsoft.com/en-us/library/system.net.cookie.secure.aspx'>.NET Cookie.Secure Property</a></li><li><a href='http://blog.teamtreehouse.com/how-to-create-totally-secure-cookies'>How to Create Totally Secure Cookies</a></li></ul></div>",
"ProofOfConcept": ""
},
{
"Url": "https://www.sampleweb.org/",
"Type": "BootstrapjsOutOfDate",
"Name": "Out-of-date Version (Bootstrap)",
"Severity": "Medium",
"Certainty": 90,
"Confirmed": false,
"Classification": {
"Owasp": "A9",
"Owasp2017": "A9",
"Wasc": null,
"Cwe": null,
"Capec": "310",
"Pci31": "6.2",
"Pci32": "6.2",
"Hipaa": null
},
"HttpRequest": {
"Method": "GET",
"Content": "GET / HTTP/1.1\r\nHost: www.sampleweb.org\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-us,en;q=0.5\r\nCache-Control: no-cache\r\nUser-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)\r\nX-Scanner: Netsparker\r\n\r\n",
"Parameters": [ ]
},
"HttpResponse": {
"StatusCode": 200,
"Duration": 644.6389,
"Content": "HTTP/1.1 200 OK\r\nX-Cache: MISS\r\nX-Timer: S1551563304.277046,VS0,VE20\r\nAge: 0\r\nCache-Control: max-age=600\r\nETag: W/\"5b8fd2e9-6807\"\r\nAccess-Control-Allow-Origin: *\r\nX-Fastly-Request-ID: 0345654a04250c6d1c420d386643c1f6dc7c3c24\r\nX-Served-By: cache-chi21166-CHI\r\nConnection: keep-alive\r\nExpires: Sat, 02 Mar 2019 21:58:24 GMT\r\nAccept-Ranges: bytes\r\nX-Cache-Hits: 0\r\nContent-Length: 5954\r\nX-GitHub-Request-Id: 0820:594C:6A9400:84F805:5C7AFA26\r\nVary: Accept-Encoding\r\nVia: 1.1 varnish\r\nLast-Modified: Wed, 05 Sep 2018 12:58:17 GMT\r\nContent-Type: text/html; charset=utf-8\r\nServer: GitHub.com\r\nDate: Sat, 02 Mar 2019 21:48:24 GMT\r\nContent-Encoding: \r\n\r\n"
},
"ExtraInformation": [
{
"Name": "Identified Version",
"Value": "4.0.0"
},
{
"Name": "Latest Version",
"Value": "4.3.1"
},
{
"Name": "Vulnerability Database",
"Value": "Result is based on 3/1/2019 vulnerability database content."
}
],
"KnownVulnerabilities": [
{
"Title": "bootstrap.js Cross-Site Scripting (XSS) Vulnerability",
"Severity": "Medium"
},
{
"Title": "bootstrap.js Cross-Site Scripting (XSS) Vulnerability",
"Severity": "Medium"
},
{
"Title": "bootstrap.js Cross-Site Scripting (XSS) Vulnerability",
"Severity": "Medium"
},
{
"Title": "bootstrap.js Cross-Site Scripting (XSS) Vulnerability",
"Severity": "Medium"
}
],
"Description": "<p>Netsparker identified that the target web site is using Bootstrap and detected that it is out of date.</p>",
"Impact": "<div>Since this is an old version of the software, it may be vulnerable to attacks.</div>",
"RemedialActions": "",
"ExploitationSkills": "",
"RemedialProcedure": "<div>\n<p>Please upgrade your installation of Bootstrap to the latest stable version.</p>\n</div>",
"RemedyReferences": "<div><ul><li><a href='https://getbootstrap.com/'>Downloading Bootstrap</a></li></ul></div>",
"ExternalReferences": "",
"ProofOfConcept": ""
},
{
"Url": "https://www.sampleweb.org/",
"Type": "CookieNotMarkedAsHttpOnly",
"Name": "Cookie Not Marked as HttpOnly",
"Severity": "Low",
"Certainty": 100,
"Confirmed": true,
"Classification": {
"Owasp": "A5",
"Owasp2017": "A6",
"Wasc": "15",
"Cwe": "16",
"Capec": "107",
"Pci31": null,
"Pci32": null,
"Hipaa": null
},
"HttpRequest": {
"Method": "GET",
"Content": "GET / HTTP/1.1\r\nHost: www.sampleweb.org\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-us,en;q=0.5\r\nCache-Control: no-cache\r\nUser-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)\r\nX-Scanner: Netsparker\r\n\r\n",
"Parameters": [ ]
},
"HttpResponse": {
"StatusCode": 200,
"Duration": 644.6389,
"Content": null
},
"ExtraInformation": [
{
"Name": "Identified Cookie(s)",
"Value": "cookieconsent_status"
},
{
"Name": "Cookie Source",
"Value": "JavaScript"
}
],
"KnownVulnerabilities": [ ],
"Description": "<p>Netsparker identified a cookie not marked as HTTPOnly.</p><p>HTTPOnly cookies cannot be read by client-side scripts, therefore marking a cookie as HTTPOnly can provide an additional layer of protection against cross-site scripting attacks.</p>",
"Impact": "<div>During a cross-site scripting attack, an attacker might easily access cookies and hijack the victim's session.</div>",
"RemedialActions": "<div><ol><li>See the remedy for solution.</li><li>Consider marking all of the cookies used by the application as HTTPOnly. (<em>After these changes javascript code will not be able to read cookies.</em>)</li></ol></div>",
"ExploitationSkills": "",
"RemedialProcedure": "<div>Mark the cookie as HTTPOnly. This will be an extra layer of defense against XSS. However this is not a silver bullet and will not protect the system against cross-site scripting attacks. An attacker can use a tool such as <a href=\"https://labs.portcullis.co.uk/tools/xss-tunnel/\" data-mce-href=\"https://labs.portcullis.co.uk/tools/xss-tunnel/\">XSS Tunnel</a> to bypass HTTPOnly protection.</div>",
"RemedyReferences": "",
"ExternalReferences": "<div><ul><li><a href='https://www.owasp.org/index.php/HTTPOnly'>OWASP HTTPOnly Cookies</a></li><li><a href='https://msdn.microsoft.com/en-us/library/system.web.httpcookie.httponly%28VS.80%29.aspx'>MSDN - ASP.NET HTTPOnly Cookies</a></li></ul></div>",
"ProofOfConcept": ""
}
]
}
14 changes: 14 additions & 0 deletions unittests/tools/test_netsparker_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,17 @@ def test_parse_file_issue_9816(self):
self.assertEqual("High", finding.severity)
self.assertEqual(614, finding.cwe)
self.assertEqual("03/02/2019", finding.date.strftime("%d/%m/%Y"))

def test_parse_file_issue_10311(self):
with open("unittests/scans/netsparker/issue_10311.json") as testfile:
parser = NetsparkerParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(3, len(findings))
for finding in findings:
for endpoint in finding.unsaved_endpoints:
endpoint.clean()
with self.subTest(i=0):
finding = findings[0]
self.assertEqual("High", finding.severity)
self.assertEqual(614, finding.cwe)
self.assertEqual("03/02/2019", finding.date.strftime("%d/%m/%Y"))

0 comments on commit 6b9fd8c

Please sign in to comment.