Skip to content

Commit

Permalink
Merge pull request DefectDojo#10354 from DefectDojo/release/2.35.1
Browse files Browse the repository at this point in the history
Release: Merge release into master from: release/2.35.1
  • Loading branch information
Maffooch authored Jun 6, 2024
2 parents 67a7571 + b163750 commit cfdc7cd
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 18 deletions.
2 changes: 1 addition & 1 deletion components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "defectdojo",
"version": "2.35.0",
"version": "2.35.1",
"license" : "BSD-3-Clause",
"private": true,
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion dojo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
# Django starts so that shared_task will use this app.
from .celery import app as celery_app # noqa: F401

__version__ = '2.35.0'
__version__ = '2.35.1'
__url__ = 'https://github.com/DefectDojo/django-DefectDojo'
__docs__ = 'https://documentation.defectdojo.com'
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
4 changes: 2 additions & 2 deletions helm/defectdojo/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
apiVersion: v2
appVersion: "2.35.0"
appVersion: "2.35.1"
description: A Helm chart for Kubernetes to install DefectDojo
name: defectdojo
version: 1.6.132
version: 1.6.133
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 cfdc7cd

Please sign in to comment.